рдореЗрд░реЗ рдкрд╛рд╕ рдмрд╣реБрдд рд╕рд╛рд░реЗ рд╕рдВрджрд░реНрдн рд╣реИрдВ рдФрд░ рдореБрдЭреЗ рдЗрд╕ рддрд░рд╣ рд╕реЗ рд▓рд┐рдЦрдирд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдмрджрд╕реВрд░рдд! рдпрд╣ рдЕрдм рдореЗрд░реЗ рдХрд╛рдо рдореЗрдВ рдмрд╛рдзрд╛ рдбрд╛рд▓рддрд╛ рд╣реИред рдРрд╕рд╛ рдбрд┐рдЬрд╝рд╛рдЗрди рдЗрд╕реЗ рд▓рдЧрднрдЧ рдЕрдиреБрдкрдпреЛрдЧреА рдмрдирд╛рддрд╛ рд╣реИред
<context1.Provider value={value1}>
<context2.Provider value={value2}>
<context3.Provider value={value3}>
<context4.Provider value={value4}>
<context5.Provider value={value5}>
</context5.Provider>
</context4.Provider>
</context3.Provider>
</context2.Provider>
</context1.Provider>
<context1.Consumer>
{value1 => <context2.Consumer>
{value2 => <context3.Consumer>
{value3 => <context4.Consumer>
{value4 => <context5.Consumer>
{value5 => (
null
)}
</context5.Consumer>}
</context4.Consumer>}
</context3.Consumer>}
</context2.Consumer>}
</context1.Consumer>
рдЖрдиреЗ рд╡рд╛рд▓реЗ рд╣реБрдХ рдПрдкреАрдЖрдИ рд╕рдВрджрд░реНрднреЛрдВ рдХрд╛ рдЙрдкрднреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЕрд▓рдЧ рддрд░реАрдХрд╛ рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВред
рдзрдиреНрдпрд╡рд╛рджред рд▓реЗрдХрд┐рди рдкреНрд░рджрд╛рддрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛?
рдореБрдЭрдореЗрдВ рдЗрдорд╛рдирджрд╛рд░реА рд░рд╣реЗрдЧреАред рдпрджрд┐ рдЖрдк рдЗрд╕ рддрд░рд╣ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХрд╛ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдбрд┐рдЬрд╝рд╛рдЗрди рдЦрд░рд╛рдм рд▓рдЧрддрд╛ рд╣реИ рдФрд░ рд╕рдВрднрд╡рддрдГ рдЖрдкрдХреЛ рд░рд┐рдПрдХреНрдЯ рд╕рдВрджрд░реНрдн рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред
рдирд╣реАрдВрдВ, рдореИрдВ рдПрдХ рдирдпрд╛ рд╕реНрдЯреЛрд░ рдХрдВрдЯреЗрдирд░ рдбрд┐рдЬрд╛рдЗрди рдХрд░ рд░рд╣рд╛ рд╣реВрдВред рдЗрд╕реЗ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рд╕рдВрджрд░реНрдн рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
https://github.com/rabbitooops/rako
рдкреНрд░рджрд╛рддрд╛рдУрдВ / рдЙрдкрднреЛрдХреНрддрд╛рдУрдВ рдХреА рдЧрд╣рд░реА 5 рдкрд░рддреЛрдВ рдХреЗ рд╕рд╛рде рдЙрд╕ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рдХреНрдпрд╛ рдХрд░рдирд╛ рд╣реИ?
рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ Redux рдЬреИрд╕реЗ рдПрдХрд▓ рд╕реНрдЯреЛрд░ рд╕рдорд╛рдзрд╛рди рдХреЗ рдмрдЬрд╛рдп рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдИ рджреБрдХрд╛рдиреЛрдВ рдХреЛ рдЗрдВрдЬреЗрдХреНрдЯ рдХрд░рдиреЗ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИред
рдЙрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рд╕рдВрджрд░реНрдн рд╣реИрдВрдбрд▓рд┐рдВрдЧ рдЕрдм рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдкрд░ рд╣реИ, рдФрд░ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдкрд░ рдХрдо рд╣реИред рд╡реЗ рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд░рддреЗ рд╣реИрдВ, рдпрд╣ рдЙрдирдХреЗ рдКрдкрд░ рд╣реИ, рдФрд░ рдпрджрд┐ рд╡реЗ рд╕рднреА рдкреНрд░рджрд╛рддрд╛рдУрдВ рдХреЛ рдПрдХ рд╕реНрдерд╛рди рдкрд░ рдЪрд╛рд╣рддреЗ рд╣реИрдВ (рдЬреЛ рдХрдИ рд╕реНрдЯреЛрд░реЛрдВ рдХреЗ рдЙрджреНрджреЗрд╢реНрдп рдХреЛ рд╣рд░рд╛рддреЗ рд╣реИрдВ), рддреЛ рдпрд╣ рдЙрдирдХреА рдкрд╕рдВрдж рд╣реИред рдЖрджрд░реНрд╢ рд░реВрдк рд╕реЗ рдЖрд╡реЗрджрди рдореЗрдВ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╡рд┐рднрд╛рдЬрди рдкрд░ рдПрдХ рдПрдХрд╛рдзрд┐рдХ рд╕реНрдЯреЛрд░ рд╕рдорд╛рдзрд╛рди рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдЗрд╕рд▓рд┐рдП рдЗрд╕ рддрд░рд╣ рдХреЗ рдиреЗрд╕реНрдЯреЗрдб рд╕рдВрджрд░реНрдн рдмрд╣реБрдд рдЕрдзрд┐рдХ рджреБрд░реНрд▓рдн рд╣реИрдВред
рдореЗрд░рд╛ 2 рд╕реЗрдВрдЯ рдХрдо рд╕реЗ рдХрдоред
рддреЛ рд╕рдВрджрд░реНрдн рдПрдкреАрдЖрдИ рдХреЗрд╡рд▓ рд╕реНрдЯреЛрд░ рдЬреИрд╕реЗ рд░реЗрдбрдХреНрд╕ рдХреЗ рд▓рд┐рдП рдЕрдиреБрдХреВрд▓ рд╣реИред
рд╣рд░реНрдЧрд┐рдЬ рдирд╣реАрдВред рд▓реЗрдХрд┐рди рдЕрдзрд┐рдХ рдпрдерд╛рд░реНрдерд╡рд╛рджреА рдЙрджрд╛рд╣рд░рдг рдХреЗ рдмрд┐рдирд╛ рдЕрдкрдиреА рд╕рдорд╕реНрдпрд╛ рдкрд░ рдЪрд░реНрдЪрд╛ рдХрд░рдирд╛ рднреА рдХрдард┐рди рд╣реИред рдХреГрдкрдпрд╛ рдПрдХ рдмрдирд╛рдПрдВ?
рдХрд▓реНрдкрдирд╛ рдХреАрдЬрд┐рдП рдХрд┐ рддреАрди рд╕реНрдЯреЛрд░ рдереАрдо, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдФрд░ рдХрд╛рдЙрдВрдЯрд░ рд╣реИрдВред
function theme(getState) {
return {
color: 'white',
setColor(color) {
this.setState({color})
}
}
}
function user(getState) {
return {
name: '',
setName(name) {
this.setState({name})
}
}
}
function counter(getState) {
return {
value: 0,
increment() {
const {value} = getState()
this.setState({value: value + 1})
}
}
}
const [themeStore, userStore, counterStore] = createStores(theme, user, counter)
const [themeContext, userContext, counterContext] = createContexts(themeStore, userStore, counterStore)
class App extends React.Component {
render() {
return (
<themeContext.StoreProvider>
<userContext.StoreProvider>
<counterContext.StoreProvider>
<Child />
</counterContext.StoreProvider>
</userContext.StoreProvider>
</themeContext.StoreProvider>
)
}
}
class Child extends React.Component {
static contextType = [themeContext, userContext]
render() {
const [theme, user] = this.context
/* ... */
}
}
рдЖрдкрдХрд╛ рдЖрджрд░реНрд╢ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдХреНрдпрд╛ рд╣реЛрдЧрд╛?
рд╕рдВрджрд░реНрдн рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред рд▓реЗрдЦрди, рдмрд┐рдирд╛ рдШреЛрдВрд╕рд▓реЗ рдХреЗ рд╢рд┐рдХрд╛рд░ рдХрдИ рд╕рдВрджрд░реНрднреЛрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░реЗрдВред
рдиреЗрд╕реНрдЯрд┐рдВрдЧ рдХреЗ рдмрд┐рдирд╛ рдХрдИ рд╕рдВрджрд░реНрднреЛрдВ рдХрд╛ рдЙрдкрднреЛрдЧ рдХрд░рдирд╛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕рдорд░реНрдерд┐рдд рд╣реИред (рд╣реБрдХ рдХреЗ рд╕рд╛рдеред)
Context.write рдореЗрдВ рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ RFC рдЦреБрд▓рд╛ рд╣реИред рд╣рдореЗрдВ рдирд╣реАрдВ рдкрддрд╛ рдХрд┐ рдпрд╣ рдорд┐рд▓реЗрдЧрд╛ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдХреБрдЫ рдмрд╣реБрдд рд╣реА рдЬрдЯрд┐рд▓ рдкреНрд░рд╢реНрди рдЙрдард╛рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЬрдм рдЖрд░рдПрдлрд╕реА рдЦреБрд▓рд╛ рд╣реИ рддреЛ рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдЗрд╕ рдореБрджреНрджреЗ рдореЗрдВ рдХреНрдпрд╛ рдХрд╛рд░реНрд░рд╡рд╛рдИ рд╣реЛрдЧреАред рдХреНрдпрд╛ рдЖрдкрдХреЗ рдкрд╛рд╕ рдЖрд░рдПрдлрд╕реА рдкреНрд░реЗрд░рдгрд╛ рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рд╣реИ?
рдореИрдВ рдПрдХ рд╕рд╡рд╛рд▓ рдкреВрдЫрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдБред рдХрдХреНрд╖рд╛ рдореЗрдВ рдХрдИ рд╕рдВрджрд░реНрднреЛрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдкрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреНрдпреЛрдВ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ? рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ API рдореЗрдВ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдореБрджреНрджреЗ рд╣рд▓ рд╣реЛрдиреЗ рд╣реИрдВ рдФрд░ рдЕрднреА рдмрд╣реБрдд рдЕрд╕реНрдерд┐рд░ рд╣реИрдВред has
static contextType = [themeContext, userContext]
const [theme, user] = this.context
рдореИрдВ рдПрдХ StoreProviders
рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдЬрд╛ рд░рд╣рд╛ рд╣реВрдВ рдЬреЛ рдХрдИ рд╕рдВрджрд░реНрднреЛрдВ рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдШреЛрдВрд╕рд▓рд╛ рдмрдирд╛ рд╕рдХрддрд╛ рд╣реИред
const StoreProviders = constructStoreProviders(...storeContexts)
<StoreProviders>
<Child />
</StoreProviders>
рдЖрдкрдХреА рдорджрдж рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж Dan! :)
@rabbitooops рдЖрдкрдХреЗ рдкрд╛рд╕ рд╣реБрдХ рдХреЗ рд╕рд╛рде рдХреМрди рд╕реЗ рдореБрджреНрджреЗ рд╣реИрдВ? рдореИрдВ рдЙрддреНрдкрд╛рджрди рдореЗрдВ рд╣реБрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВ рдФрд░ рд╡реЗ рдореЗрд░реА рдЯреАрдо рдХреЗ рд▓рд┐рдП рдЕрдЪреНрдЫрд╛ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВред
рдФрд░ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛? рдЕрднреА рд╣реБрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╕реБрд░рдХреНрд╖рд┐рдд рд╣реИред @gaearon
// A library
function useStoreProviders(Component, ...contexts) {
contexts.forEach(context => Component.useProvider(context, someValue))
}
// User code
function App(props) {
const [theme] = useState('white')
// Safe to use `component hook`.
App.useProvider(themeContext, theme)
App.useShouldComponentUpdate(() => {})
// Meanwhile, library can also use `component hook`.
useStoreProviders(App, storeContext1, storeContext2, storeContext3)
// Normal hook can't use `component hook`.
customHook()
/* ... */
}
<App />
decorateBeforeRender(App)
@rabbitooops https://github.com/reactjs/rfcs/issues/101
@rabbitooops рд╕реНрдЯреЛрд░ рдХреА рдмрд╣реБ-рдкрд░рддреЛрдВ рдХреА рдирдХрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдВрдЬреА рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХрд▓ рд╕реНрдЯреЛрд░ рдФрд░ рд╕рд┐рдВрдмрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреИрд╕реЗ?
data Store = Leaf Object | C Store Store
рдпрд╛ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдПрдХ рдЕрдкреВрд░реНрдг рддрд░реАрдХреЗ рд╕реЗ:
const LEFT = Symbol('LEFT')
const RIGHT = Symbol('RIGHT')
function createLeafStore = return new Store({});
function createStore(leftChild :: Store, rightChild :: Store) {
return new Store({[LEFT]: leftChild, [Right]: rightChild})
}
@TrySound рдЕрд▓рдЧ: App.useProvider
@zhujinxuan рдореБрдЭреЗ рдЦреЗрдж рд╣реИ, рдореИрдВ рдЖрдкрд╕реЗ рдирд╣реАрдВ рдорд┐рд▓ рд╕рдХрддрд╛ред
@zhujinxuan рдЖрдк рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЕрдирдХрд╣рд╛ , рдЙрджрд╛рд╣рд░рдг:
<Subscribe to={[AppContainer, CounterContainer, ...]}>
{(app, counter, ...) => (
<Child />
)}
</Subscribe>
рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдПрдкреАрдЖрдИ рдореЗрдВ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдореБрджреНрджреЛрдВ рдХреЛ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рд╣реИ рдФрд░ рдЕрднреА рдмрд╣реБрдд рдЕрд╕реНрдерд┐рд░ рд╣реИ
рд╣рдо рдЗрд╕реЗ рдПрдХ рдпрд╛ рджреЛ рд╕рдкреНрддрд╛рд╣ рдХреЗ рднреАрддрд░ рдЬрд╛рд░реА рдХрд░рдиреЗ рдХреА рддреИрдпрд╛рд░реА рдХрд░ рд░рд╣реЗ рд╣реИрдВ - рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдирд╣реАрдВ рд╣реИ рдХрд┐ рдЖрдкрдиреЗ рдЗрд╕рдХрд╛ рдЕрдиреБрдорд╛рди рдХреНрдпреЛрдВ рд▓рдЧрд╛рдпрд╛ рд╣реИред рд╡реЗ рдЬрд▓реНрдж рд╣реА рддреИрдпрд╛рд░ рд╣реЛ рдЬрд╛рдПрдВрдЧреЗ рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрджрд┐ рдЖрдк рд╕реБрд░рдХреНрд╖рд┐рдд рд░рд╣рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдХреГрдкрдпрд╛ рд╕реНрдерд┐рд░ рд░рд┐рд▓реАрдЬ рддрдХ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░реЗрдВред
рдФрд░ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛?
рдПрдХ рд▓реВрдк рдореЗрдВ рд╣реБрдХ рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ (рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк forEach
) рдЖрдорддреМрд░ рдкрд░ рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рд╣реИред рдЗрд╕ рддрд░рд╣ рд╕реЗ рдореБрджреНрджреЛрдВ рдХреЛ рд╕реБрд▓рдЭрд╛рдирд╛ рдЖрд╕рд╛рди рд╣реИред
useStoreProviders
рджреЛрдиреЛрдВ useProvider
рдФрд░ useShouldComponentUpdate
рд╣реБрдХ рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдорд╕реНрдпрд╛рдЧреНрд░рд╕реНрдд рд╣реИрдВ (рдпрд╣реА рд╡рдЬрд╣ рд╣реИ рдХрд┐ рд░рд┐рдПрдХреНрдЯ рдЙрдирдХреЗ рдкрд╛рд╕ рдирд╣реАрдВ рд╣реИ)ред Https://github.com/facebook/react/issues/14534#issuecomment -455411117 рдкрд░ рдореЗрд░реА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рджреЗрдЦреЗрдВред
рдХреБрд▓ рдорд┐рд▓рд╛рдХрд░, рдореИрдВ рдЗрд╕ рдореБрджреНрджреЗ рдХреЗ рдЗрд░рд╛рджреЗ рдХреЛ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдВрдШрд░реНрд╖ рдХрд░ рд░рд╣рд╛ рд╣реВрдВред
рдХрдИ рд╕рдВрджрд░реНрднреЛрдВ рдХрд╛ рдЙрдкрднреЛрдЧ useContext
рд╣реБрдХ рджреНрд╡рд╛рд░рд╛ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╣рдо рдЗрд╕реЗ рдПрд░реЗрдЬрд╝ рдХреЗ рд╕рд╛рде рдХрд┐рд╕реА рднреА рддрд░рд╣ "рд╕реНрд╡рдЪрд╛рд▓рд┐рдд" рдХрд░рдиреЗ рдХреА рдЕрдиреБрд╢рдВрд╕рд╛ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рд╕реЗ рдРрд╕реЗ рдШрдЯрдХреЛрдВ рдХреЛ рд▓рд┐рдЦрдирд╛ рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рдЬреЛ рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╕рдВрджрд░реНрднреЛрдВ рдХреА рд╕рджрд╕реНрдпрддрд╛ рд▓реЗрддреЗ рд╣реИрдВ рдФрд░ рдмрд╣реБрдд рдмрд╛рд░ рдлрд┐рд░ рд╕реЗ рдкреНрд░рд╕реНрддреБрдд рдХрд░рддреЗ рд╣реИрдВред рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рд╕реНрдкрд╖реНрдЯ рдЕрд░реНрде рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдХреМрди рд╕рд╛ рдШрдЯрдХ рдПрдХ рдШрдЯрдХ рдХреЛ рд╕реБрдирддрд╛ рд╣реИ, рдЬреЛ рдХрд┐ useContext
API рдЖрдкрдХреЛ рджреЗрддрд╛ рд╣реИред рдпрджрд┐ рдЖрдкрдХреЛ рдЪрд╛рд╣рд┐рдП, рддреЛ рдЖрдк useMyContexts()
рд╣реБрдХ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕рдВрджрд░реНрднреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдореИрдВ рдЖрдкрдХреЛ рдЗрд╕реЗ рдЧрддрд┐рд╢реАрд▓ рдмрдирд╛рдиреЗ рдХреА рд╕рд▓рд╛рд╣ рдирд╣реАрдВ рджреЗрддрд╛, рдХреНрдпреЛрдВрдХрд┐ рдЕрдЧрд░ рд╕рд░рдгреА рдХреА рд▓рдВрдмрд╛рдИ рдмрджрд▓рддреА рд╣реИ, рддреЛ рдпрд╣ рдЯреВрдЯ рд╕рдХрддреА рд╣реИред
рдХрдИ рдкреНрд░рджрд╛рддрд╛рдУрдВ рдХреЛ "рдмреЙрдпрд▓рд░рдкреНрд▓реЗрдЯ" рдХреЗ рд░реВрдк рдореЗрдВ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЕрдВрддрддрдГ рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдорд╛рдзрд╛рди рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдореИрдВ рдпрд╣ рднреА рдирд╣реАрдВ рд╕рдордЭрддрд╛ рдХрд┐ рдЖрдк рдЗрд╕реЗ рдПрдХ рдмрдбрд╝реА рд╕рдорд╕реНрдпрд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдХреНрдпреЛрдВ рджреЗрдЦрддреЗ рд╣реИрдВред рдЗрд╕ рдереНрд░реЗрдб рдХреЗ рдЙрджрд╛рд╣рд░рдг рдореЗрд░реЗ рд▓рд┐рдП рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рд╕рдордЭрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рдпрдерд╛рд░реНрдерд╡рд╛рджреА рдирд╣реАрдВ рд╣реИрдВред рдореБрдЭреЗ JSX рдХреА рдХрдИ рдкрд░рддреЛрдВ рдХреЗ рд╕рд╛рде рдХреБрдЫ рднреА рдмреБрд░рд╛ рдирд╣реАрдВ рджрд┐рдЦ рд░рд╣рд╛ рд╣реИ рдЬреЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рд╢реАрд░реНрд╖ рдкрд░ рдХрд╣реАрдВ рд╣реИред рдмрд╣реБрдд рдпрдХреАрди рд╣реИ рдХрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдЕрдзрд┐рдХрд╛рдВрд╢ рдШрдЯрдХреЛрдВ рдореЗрдВ div
рдШреЛрдВрд╕рд▓реЗ рдмрд╣реБрдд рдЧрд╣рд░реЗ рд╣реИрдВ рдФрд░ рдЗрд╕рд╕реЗ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдЪреЛрдЯ рдирд╣реАрдВ рд▓рдЧрддреА рд╣реИ
рдореИрдВ рдЗрд╕реЗ рдмрдВрдж рдХрд░ рджреВрдВрдЧрд╛ рдХреНрдпреЛрдВрдХрд┐ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореИрдВрдиреЗ рдкрд╣рд▓реЗ рд╣реА рдЗрди рдмрд┐рдВрджреБрдУрдВ рдкрд░ рдЬрд╡рд╛рдм рджрд┐рдпрд╛ рдерд╛, рдФрд░ рдЪрд░реНрдЪрд╛ рд╣рд▓рдХреЛрдВ рдореЗрдВ рдЬрд╛рддреА рд╣реИред рдЕрдЧрд░ рдХреБрдЫ рдпрд╛рдж рдЖ рд░рд╣рд╛ рд╣реИ рддреЛ рдореБрдЭреЗ рдмрддрд╛рдПрдВред
OT: @gaearon , useRender
рдЬреИрд╕реА рдХреБрдЫ рдЬреЛрдбрд╝рдиреЗ рдХреА рдХреЛрдИ рдпреЛрдЬрдирд╛ рд╣реИ рдпрд╛ рд░реЗрдВрдбрд░рд┐рдВрдЧ рдХрд╛ рдЕрдзрд┐рдХ рдирд┐рдпрдВрддреНрд░рдг рд╣реИ? рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:
useRender(() => <div />, [...props])
рджреВрд╕рд░реЗ arg рдореЗрдВ useEffect
рд╣реБрдХ рдХреА рд╕рдорд╛рди рднреВрдорд┐рдХрд╛ рд╣реИред
useMemo
рдЖрдкрдХрд╛ рдорд┐рддреНрд░ рд╣реИред
Https://reactjs.org/docs/hooks-faq.html#how -to-memoize-рдЧрдгрдирд╛ рдореЗрдВ рджреВрд╕рд░рд╛ рд╕реНрдирд┐рдкреЗрдЯ рджреЗрдЦреЗрдВред
рдореИрдВ рдЗрд╕ рддрд░рд╣ рдПрдХ рдХреЛрдб рдХреЗ рд╕рд╛рде рд╕рдорд╛рдкреНрдд рд╣реБрдЖ:
function provider<T>(theProvider: React.Provider<T>, value: T) {
return {
provider: theProvider,
value
};
}
function MultiProvider(props: {providers: Array<{provider: any; value: any}>; children: React.ReactElement}) {
let previous = props.children;
for (let i = props.providers.length - 1; i >= 0; i--) {
previous = React.createElement(props.providers[i].provider, {value: props.providers[i].value}, previous);
}
return previous;
}
рддрдм рдореЗрд░реЗ рд╢реАрд░реНрд╖-рд╕реНрддрд░реАрдп рдШрдЯрдХ рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВ:
public render() {
return (
<MultiProvider
providers={[
provider(Context1.Provider, this.context1),
provider(Context2.Provider, this.context2),
provider(Context3.Provider, this.context3),
provider(Context4.Provider, this.context4),
provider(Context5.Provider, this.context5),
]}
><AppComponents />
</MultiProvider>
}
@gaearon
рдореБрдЭреЗ JSX рдХреА рдХрдИ рдкрд░рддреЛрдВ рдХреЗ рд╕рд╛рде рдХреБрдЫ рднреА рдмреБрд░рд╛ рдирд╣реАрдВ рджрд┐рдЦ рд░рд╣рд╛ рд╣реИ рдЬреЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рд╢реАрд░реНрд╖ рдкрд░ рдХрд╣реАрдВ рд╣реИред
рдореЗрд░реЗ рдкрд╛рд╕ ~ 15 рдирд┐рд░реНрднрд░рддрд╛рдПрдВ рд╣реИрдВ рдЬреЛ рдореИрдВ рдЙрд╕ рддрд░реАрдХреЗ рд╕реЗ рдЗрдВрдЬреЗрдХреНрдЯреЗрдмрд▓ рд╣реЛрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ, рдФрд░ рдЗрдВрдбреЗрдВрдЯреЗрд╢рди рдХреЗ 15 рд╕реНрддрд░ рдореЗрд░реЗ рд▓рд┐рдП рдмрд╣реБрдд рд╕реБрдВрджрд░ рдирд╣реАрдВ рд▓рдЧрддреЗ рд╣реИрдВ :)
@ 0xorial рдЖрдкрдХреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рдШрдЯрдХ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рд╕рдм рдХреЗ рдмрд╛рдж <> рдХреЗрд╡рд▓ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рд╣реИ React.createElementред рддреЛ рдЖрдк рдЗрд╕реЗ рдХрдВрдкреЛрдЬрд╝ рдлрдВрдХреНрд╢рди рдореЗрдВ рд╕рд░рд▓ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдЬреИрд╕реЗ:
const compose = (contexts, children) =>
contexts.reduce((acc, [Context, value]) => {
return <Context.Provider value={value}>{acc}</Context.Provider>;
}, children);
рдФрд░ рдЗрд╕реЗ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ:
import Context1 from './context1';
import Context2 from './context2';
import Context3 from './context3';
...
import Context15 from './context15';
const MyComponent = (props) => {
// const value1..15 = ... get the values from somewhere ;
return compose(
[
[Context1, value1],
[Context2, value2],
[Context3, value3],
...
[Context15, value15],
],
<SomeSubComponent/>
);
}
рдореИрдВрдиреЗ рдЕрддреАрдд рдореЗрдВ рдПрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд▓рд┐рдЦрд╛ рдерд╛ рдЬреЛ рдЗрд╕ рдорд╛рдорд▓реЗ рдХреЛ рд╕рдВрднрд╛рд▓рддрд╛ рд╣реИ: https://github.com/disjukr/join-react-context
рдпрд╣ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдХреБрдЫ рдРрд╕рд╛ рд╣реИ рдЬреЛ рд╣рд░ рд╕рдордп рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдореЗрдВ рд╣реЛрддрд╛ рд╣реИред useContext
рдПрдХ рдШрдЯрдХ рдореЗрдВ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рдбреЗрдЯрд╛ _consuming_ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЬрдм рдЖрдк рдХрдИ рдкреНрд░рджрд╛рддрд╛рдУрдВ рд╡рд╛рд▓реЗ рдРрдк рдореЗрдВ _provide_ рд╕рдВрджрд░реНрдн рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ рддреЛ рдпрд╣ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред
рдпрд╣рд╛рдВ @alesmenzelsocialbakers рд╕рдорд╛рдзрд╛рди рдХрд╛ рдПрдХ рдмрдВрдж рд╡рд┐рдХрд▓реНрдк рд╣реИ:
const composeProviders = (...Providers) => (Child) => (props) => (
Providers.reduce((acc, Provider) => (
<Provider>
{acc}
</Provider>
), <Child {...props} />)
)
const WrappedApp = composeProviders(
ProgressProvider,
IntentsProvider,
EntitiesProvider,
MessagesProvider
)(App)
ReactDOM.render(<WrappedApp />, document.getElementById('root'));
рдирдХрд╛рд░рд╛рддреНрдордХ рдкрдХреНрд╖ рдпрд╣ рд╣реИ рдХрд┐ рдЖрдкрдХреЛ рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреНрд░рджрд╛рддрд╛ рдШрдЯрдХ рд▓рд┐рдЦрдирд╛ рд╣реЛрдЧрд╛ред
рдЙрджрд╛рд╣рд░рдг:
export const ProgressProvider = ({ children }) => {
const [progress, setProgress] = useState(0)
return (
<ProgressContext.Provider value={{ progress, setProgress }}>
{children}
</ProgressContext.Provider>
)
}
рдореИрдВрдиреЗ рдПрдХ рд░рд╛рдЬреНрдп рдкреНрд░рдмрдВрдзрди рдкреБрд╕реНрддрдХрд╛рд▓рдп рдмрдирд╛рдпрд╛ рд╣реИ рдЬреЛ рд╕реЗрд╡рд╛ рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ рдмреЗрд╣рддрд░ рд╣реИред рдпрд╣рд╛рдБ рдкреНрд░рджрд╛рддрд╛ рдирд░рдХ рд╕реЗ рдмрдЪрдиреЗ рдХрд╛ рдПрдХ рдбреЗрдореЛ рд╣реИ ред рдЗрд╕реЗ рдЖрдЬрд╝рдорд╛рдиреЗ рдпрд╛ рдЗрд╕рдХреЗ рд╕реНрд░реЛрдд (рдХреЛрдб рдХреА 100 рд▓рд╛рдЗрдиреЗрдВ) рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рддрдВрддреНрд░ рдорд╣рд╕реВрд╕ рдХрд░реЗрдВ!
рдпрд╣ рд╕рдВрджрд░реНрдн рдкреНрд░рджрд╛рддрд╛ рдХреЛ рдЗрдХрдЯреНрдард╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ "рдЧреБрдВрдЬрд╛рдЗрд╢" рд╡рд╕реНрддреБ рдХрд╛ рдкрд░рд┐рдЪрдп рджреЗрддрд╛ рд╣реИ, рддрд╛рдХрд┐:
рдореИрдВрдиреЗ рдЗрд╕ рдкрд░ рдПрдХ рджрд░рд╛рд░ рднреА рд▓реАред рдпрд╣ рдареАрдХ рдХрд╛рдо рдХрд░рдиреЗ рд▓рдЧрддрд╛ рд╣реИ:
const composeWrappers = (
wrappers: React.FunctionComponent[]
): React.FunctionComponent => {
return wrappers.reduce((Acc, Current): React.FunctionComponent => {
return props => <Current><Acc {...props} /></Current>
});
}
рдЙрдкрдпреЛрдЧ рд╣реИ:
const SuperProvider = composeWrappers([
props => <IntlProvider locale={locale} messages={messages} children={props.children} />,
props => <ApolloProvider client={client}>{props.children}</ApolloProvider>,
props => <FooContext.Provider value={foo}>{props.children}</FooContext.Provider>,
props => <BarContext.Provider value={bar}>{props.children}</BarContext.Provider>,
props => <BazContext.Provider value={baz}>{props.children}</BazContext.Provider>,
]);
return (
<SuperProvider>
<MainComponent />
</SuperProvider>
);
рдореИрдВрдиреЗ рдЗрд╕ рд╣реЗрд▓реНрдкрд░ рдХреЛ рдПрдХ npm рд▓рд╛рдЗрдмреНрд░реЗрд░реА react-compose-wrappers
рд░реВрдк рдореЗрдВ рднреА рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд┐рдпрд╛
рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рджрд┐рдЦрд╛рддрд╛ рд╣реИ рдХрд┐ рдореИрдВ рдХреИрд╕реЗ рдкреНрд░рдорд╛рдгреАрдХреГрдд рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рдЖрд╕рдкрд╛рд╕ рдШрдЯрдХреЛрдВ рдХреЗ рд▓рд┐рдП рдЧреБрдЬрд░ рд░рд╣рд╛ рд╣реВрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рдореИрдВрдиреЗ рдЕрдкрдиреЗ рдЖрд╡реЗрджрди рдХреЗ рд▓рд┐рдП рдПрдХ рд░рд╛рдЬреНрдп рдмрдирд╛рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ред рдЕрдкрдиреА State.js рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдореИрдВрдиреЗ рдЕрдкрдиреА рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╕реНрдерд┐рддрд┐, рд╕рдВрджрд░реНрдн, Reducer, рдкреНрд░рджрд╛рддрд╛ рдФрд░ рд╣реБрдХ рд╕реЗрдЯ рдХрд┐рдпрд╛ред
import React, { createContext, useContext, useReducer } from 'react';
const INITIAL_STATE = {}
const Context = createContext();
const reducer = (state, action) =>
action
? ({ ...state, [action.type]: action[action.type] })
: state;
export const Provider = ({ children }) => (
<Context.Provider value={ useReducer(reducer, INITIAL_STATE) }>
{ children }
</Context.Provider>
);
const State = () => useContext(Context);
export default State;
рдлрд┐рд░ рдЕрдкрдиреЗ index.js рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдореИрдВрдиреЗ рдкреНрд░рджрд╛рддрд╛ рдореЗрдВ рдЕрдкрдирд╛ рдРрдк рд▓рдкреЗрдЯрд╛ред
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from './State';
import App from './App';
ReactDOM.render(
<React.StrictMode>
<Provider>
<App />
</Provider>
</React.StrictMode>,
document.getElementById('root'),
);
рдПрдХ рдШрдЯрдХ рдореЗрдВ рд░рд╛рдЬреНрдп рдХрд╛ рдЙрдкрднреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдореИрдВ рд╣реБрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВред рдореИрдВ рд░рд╛рдЬреНрдп рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░реЗрд╖рдг рдХрд╛ рднреА рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдпрджрд┐ рдореИрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдпрд╛ рд╕реЗрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред
import React, {useEffect} from 'react';
import State from './State'
const ExampleComponent = () => {
const [{ user }, dispatch] = State();
useEffect(() => {
const getUser = async () => {
const data = await fetch('http://example.com/user.json'); // However you get your data
dispatch({ type: 'user', user: data });
}
getUser();
}, [dispatch]);
// Don't render anything until user is retrieved
// The user is undefined since I passed an empty object as my initial state
if(user === undefined) return null;
return(
<p>{user.name}</p>
);
}
export default ExampleComponent;
рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдореБрдЭреЗ рд░рд╛рдЬреНрдп рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреА рд╕реНрд╡рддрдВрддреНрд░рддрд╛ рдорд┐рд▓рддреА рд╣реИ рдХрд┐ рдореБрдЭреЗ рдПрдХ рдЯрди рдЕрддрд┐рд░рд┐рдХреНрдд рд╕рдВрджрд░реНрднреЛрдВ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рдмрд┐рдирд╛ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреИрд╕реЗ рд╣реИ рдФрд░ рдкреНрд░рджрд╛рддрд╛рдУрдВ рдХреЗ рдЧрд╣рд░реЗ рдШреЛрдВрд╕рд▓реЗ рд╕реЗ рдмрдЪрдиреЗ рдореЗрдВ рдореЗрд░реА рдорджрдж рдХрд░рддрд╛ рд╣реИред
рдЖрдиреЗ рд╡рд╛рд▓реЗ рд╣реБрдХ рдПрдкреАрдЖрдИ рд╕рдВрджрд░реНрднреЛрдВ рдХрд╛ рдЙрдкрднреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЕрд▓рдЧ рддрд░реАрдХрд╛ рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВред
рдореИрдВ рдЗрд╕реЗ рдХрдХреНрд╖рд╛ рдШрдЯрдХ рдореЗрдВ рдХреИрд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд░реВрдВ?
рдЖрдиреЗ рд╡рд╛рд▓реЗ рд╣реБрдХ рдПрдкреАрдЖрдИ рд╕рдВрджрд░реНрднреЛрдВ рдХрд╛ рдЙрдкрднреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЕрд▓рдЧ рддрд░реАрдХрд╛ рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВред
https://reactjs.org/docs/hooks-reference.html#usecontextрдореИрдВ рдЗрд╕реЗ рдХрдХреНрд╖рд╛ рдШрдЯрдХ рдореЗрдВ рдХреИрд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд░реВрдВ?
рд▓реЗрдЦрди рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рдмрд┐рдирд╛ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХрд╛ рд▓рд╛рдн рд▓реЗрдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рд╣реБрдХ рдирд╣реАрдВ рд╣реИрдВ?
рдЦреИрд░, рдпрд╣реА рд╣реИ, рд╕рдм рдХреБрдЫ рдЬреЛ рд╡рд┐рднрд┐рдиреНрди рд╣реБрдХ рдХрд░рддреЗ рд╣реИрдВ, рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХрдХреНрд╖рд╛рдУрдВ рдореЗрдВ рдореМрдЬреВрдж рд╣реИрдВред рдпрджрд┐ рдЖрдк рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╡рд╛рдХреНрдп рд░рдЪрдирд╛ рдФрд░ рдЙрдкрдпреЛрдЧ рдПрдкреА рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рддреЛ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХрдХреНрд╖рд╛рдУрдВ рд╕реЗ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдШрдЯрдХреЛрдВ рддрдХ рдЪрд▓реА рдЬрд╛рддреА рд╣реИ, рдЗрд╕рд▓рд┐рдП рдлрд╝рдВрдХреНрд╢рди рдФрд░ рд╣реБрдХ рдореЗрдВ рдЖрдкрдХрд╛ рд╕реНрд╡рд╛рдЧрдд рд╣реИ)
рдореИрдВрдиреЗ vue3 рдХреЗ рд╕рд╛рде рд╕рдорд╛рди рдПрдкреАрдЖрдИ рдкреНрд░рджрд╛рди рдХрд░рдХреЗ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреИрдХреЗрдЬ рдмрдирд╛рдпрд╛
https://github.com/TotooriaHyperion/react-multi-provide
рд╕реВрдЪрдирд╛:
Outer.tsx
import React, { useMemo } from "react";
import { Providers, useCreateContexts, useProvide } from "../..";
import { createService, ServiceA } from "./service";
export const Outer: React.FC = ({ children }) => {
const contexts = useCreateContexts();
const service = useMemo(createService, []);
useProvide(contexts, ServiceA.id, service);
return <Providers contexts={contexts}>{children}</Providers>;
};
Inner2.tsx
import React from "react";
import { useContexts, useReplaySubject } from "../..";
import { ServiceA } from "./service";
export const Inner2: React.FC = () => {
const [
{
state$,
actions: { inc, dec },
},
] = useContexts([ServiceA.id]);
const count = useReplaySubject(state$);
return (
<>
<p>{count}</p>
<div>
<button onClick={inc}>Increment</button>
<button onClick={dec}>Decrement</button>
</div>
</>
);
};
рдпрд╣рд╛рдБ рд╣реИ рдХрд┐ рдореИрдВ рдпрд╣ рдХреИрд╕реЗ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдБ:
interface Composable {
(node: React.ReactNode): React.ReactElement
}
const composable1: Composable = (node)=>{
return <someContext.Provider>{node}</someContext.Provider>
}
function Comp({children}:{children?:React.ReactNode}){
return pipe(
composabl1, composabl2, composable3
)(children)
}
рдЖрдк рдХрдИ рд▓реЛрдХрдкреНрд░рд┐рдп рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдЬреИрд╕реЗ rxjs рдореЗрдВ pipe
рдлрд╝рдВрдХреНрд╢рди рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕ рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдЬреИрд╕реА рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреЗ рд▓рд┐рдП рдХрдИ рднрд╛рд╖рд╛-рд╕реНрддрд░ рдХреЗ рдкреНрд░рд╕реНрддрд╛рд╡ рднреА рд╣реИрдВред рдПрдХ рдФрд░ рдкрд░рд┐рд╡рд╛рдж рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕реЗ 'рд╣рд▓' рдХрд░рдиреЗ рдХреА рдХреЛрдИ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред
рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА
@ 0xorial рдЖрдкрдХреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рдШрдЯрдХ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рд╕рдм рдХреЗ рдмрд╛рдж <> рдХреЗрд╡рд▓ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рд╣реИ React.createElementред рддреЛ рдЖрдк рдЗрд╕реЗ рдХрдВрдкреЛрдЬрд╝ рдлрдВрдХреНрд╢рди рдореЗрдВ рд╕рд░рд▓ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдЬреИрд╕реЗ:
рдФрд░ рдЗрд╕реЗ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ: