React: рдиреЗрд╕реНрдЯреЗрдб рд╕рдВрджрд░реНрднреЛрдВ рдХреЛ рдХреИрд╕реЗ рд╣рд▓ рдХрд░реЗрдВрдЧреЗ?

рдХреЛ рдирд┐рд░реНрдорд┐рдд 18 рдЬрдире░ 2019  ┬╖  38рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: facebook/react

рдореЗрд░реЗ рдкрд╛рд╕ рдмрд╣реБрдд рд╕рд╛рд░реЗ рд╕рдВрджрд░реНрдн рд╣реИрдВ рдФрд░ рдореБрдЭреЗ рдЗрд╕ рддрд░рд╣ рд╕реЗ рд▓рд┐рдЦрдирд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдмрджрд╕реВрд░рдд! рдпрд╣ рдЕрдм рдореЗрд░реЗ рдХрд╛рдо рдореЗрдВ рдмрд╛рдзрд╛ рдбрд╛рд▓рддрд╛ рд╣реИред рдРрд╕рд╛ рдбрд┐рдЬрд╝рд╛рдЗрди рдЗрд╕реЗ рд▓рдЧрднрдЧ рдЕрдиреБрдкрдпреЛрдЧреА рдмрдирд╛рддрд╛ рд╣реИред

<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>

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

@ 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/>
  );
}

рд╕рднреА 38 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

рдЖрдиреЗ рд╡рд╛рд▓реЗ рд╣реБрдХ рдПрдкреАрдЖрдИ рд╕рдВрджрд░реНрднреЛрдВ рдХрд╛ рдЙрдкрднреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЕрд▓рдЧ рддрд░реАрдХрд╛ рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВред

https://reactjs.org/docs/hooks-reference.html#usecontext

рдзрдиреНрдпрд╡рд╛рджред рд▓реЗрдХрд┐рди рдкреНрд░рджрд╛рддрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛?

рдореБрдЭрдореЗрдВ рдЗрдорд╛рдирджрд╛рд░реА рд░рд╣реЗрдЧреАред рдпрджрд┐ рдЖрдк рдЗрд╕ рддрд░рд╣ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХрд╛ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдбрд┐рдЬрд╝рд╛рдЗрди рдЦрд░рд╛рдм рд▓рдЧрддрд╛ рд╣реИ рдФрд░ рд╕рдВрднрд╡рддрдГ рдЖрдкрдХреЛ рд░рд┐рдПрдХреНрдЯ рд╕рдВрджрд░реНрдн рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдирд╣реАрдВрдВ, рдореИрдВ рдПрдХ рдирдпрд╛ рд╕реНрдЯреЛрд░ рдХрдВрдЯреЗрдирд░ рдбрд┐рдЬрд╛рдЗрди рдХрд░ рд░рд╣рд╛ рд╣реВрдВред рдЗрд╕реЗ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рд╕рдВрджрд░реНрдн рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
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 рд╕реНрдЯреЛрд░ рдХреА рдмрд╣реБ-рдкрд░рддреЛрдВ рдХреА рдирдХрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдВрдЬреА рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХрд▓ рд╕реНрдЯреЛрд░ рдФрд░ рд╕рд┐рдВрдмрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреИрд╕реЗ?

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

react11

рдпрд╣ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдХреБрдЫ рдРрд╕рд╛ рд╣реИ рдЬреЛ рд╣рд░ рд╕рдордп рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдореЗрдВ рд╣реЛрддрд╛ рд╣реИред 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

рдореИрдВ рдЗрд╕реЗ рдХрдХреНрд╖рд╛ рдШрдЯрдХ рдореЗрдВ рдХреИрд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд░реВрдВ?

рдЖрдиреЗ рд╡рд╛рд▓реЗ рд╣реБрдХ рдПрдкреАрдЖрдИ рд╕рдВрджрд░реНрднреЛрдВ рдХрд╛ рдЙрдкрднреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЕрд▓рдЧ рддрд░реАрдХрд╛ рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВред
https://reactjs.org/docs/hooks-reference.html#usecontext

рдореИрдВ рдЗрд╕реЗ рдХрдХреНрд╖рд╛ рдШрдЯрдХ рдореЗрдВ рдХреИрд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд░реВрдВ?

рд▓реЗрдЦрди рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рдмрд┐рдирд╛ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХрд╛ рд▓рд╛рдн рд▓реЗрдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рд╣реБрдХ рдирд╣реАрдВ рд╣реИрдВ?
рдЦреИрд░, рдпрд╣реА рд╣реИ, рд╕рдм рдХреБрдЫ рдЬреЛ рд╡рд┐рднрд┐рдиреНрди рд╣реБрдХ рдХрд░рддреЗ рд╣реИрдВ, рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХрдХреНрд╖рд╛рдУрдВ рдореЗрдВ рдореМрдЬреВрдж рд╣реИрдВред рдпрджрд┐ рдЖрдк рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╡рд╛рдХреНрдп рд░рдЪрдирд╛ рдФрд░ рдЙрдкрдпреЛрдЧ рдПрдкреА рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рддреЛ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХрдХреНрд╖рд╛рдУрдВ рд╕реЗ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдШрдЯрдХреЛрдВ рддрдХ рдЪрд▓реА рдЬрд╛рддреА рд╣реИ, рдЗрд╕рд▓рд┐рдП рдлрд╝рдВрдХреНрд╢рди рдФрд░ рд╣реБрдХ рдореЗрдВ рдЖрдкрдХрд╛ рд╕реНрд╡рд╛рдЧрдд рд╣реИ)

рдореИрдВрдиреЗ vue3 рдХреЗ рд╕рд╛рде рд╕рдорд╛рди рдПрдкреАрдЖрдИ рдкреНрд░рджрд╛рди рдХрд░рдХреЗ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреИрдХреЗрдЬ рдмрдирд╛рдпрд╛

https://github.com/TotooriaHyperion/react-multi-provide

  • рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░реЗрдВ рдЬреЛ рд╕рдВрджрд░реНрдн рдХреЛ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рджреЗрддрд╛ рд╣реИ рдЕрддрд┐рд░рд┐рдХреНрдд рджреГрд╢реНрдп рдкреЗрдбрд╝ рд▓реЗрддрд╛ рд╣реИред
  • рдпрд╣ рднреА рдХрд┐ рдХреНрдпрд╛ рдЗрдВрдЬреЗрдХреНрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдХреА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓рддрд╛ рдХреЛ рд╕рдВрд░рдХреНрд╖рд┐рдд рдХрд░реЗрдВ
  • рдкреНрд░рджрд╛рддрд╛рдУрдВ рдХреЗ рдмреАрдЪ рднрдЧреНрди
  • рдирд┐рд░реНрднрд░рддрд╛ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП WeakMap рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ
  • рдмреЗрд╣рддрд░ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╕рдорд░реНрдерди, рдирд┐рд░реНрднрд░рддрд╛ рдЗрдВрдЬреЗрдХреНрд╢рди рдФрд░ рдбрд┐рдмрдЧ рдЕрдиреБрднрд╡ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдСрдмреНрдЬреЗрдХреНрдЯ рд▓рд┐рдкрдЯреЗ рдкреНрд░рддреАрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ

рд╕реВрдЪрдирд╛:

  • рдореИрдВ рдЖрдкрдХреЛ рд╕рдВрджрд░реНрдн рдХреА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓рддрд╛ рдкрд░ рдмрд╣реБрдд рдЕрдзрд┐рдХ рднрд░реЛрд╕рд╛ рдХрд░рдиреЗ рдХреА рд╕рд▓рд╛рд╣ рдирд╣реАрдВ рджреЗрддрд╛, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдбреЗрдЯрд╛ рддрдХ рдкрд╣реБрдВрдЪ рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп @gaearon рдиреЗ рдХрд╣рд╛ рд╣реИ рдХрд┐ рдмрд╣реБрдд рд╕рд╛рд░реЗ рд╕рдВрджрд░реНрднреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рджрд╕реНрдпрддрд╛ рдирд╣реАрдВ рд╕рд╣реА рдереАред рд▓реЗрдХрд┐рди рдЙрдиреНрд╣реЛрдВрдиреЗ рдЙрд▓реНрд▓реЗрдЦ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдХрд┐ рд╕рдВрджрд░реНрдн рдХреА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдкрд░ рднрд░реЛрд╕рд╛ рдХрд░рдХреЗ рдбреЗрдЯрд╛ рд╕рджрд╕реНрдпрддрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдпрд╣ рдПрдХ рдЧрд▓рдд рдкреИрдЯрд░реНрди рд╣реИ ред рдЗрд╕рд▓рд┐рдП рд╕рд╣реА рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдХрдИ рд╕рдВрджрд░реНрднреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рди рдХрд░реЗрдВ рдмрд▓реНрдХрд┐ рдПрдХ рд╕рдВрджрд░реНрдн рдореЗрдВ рдЕрдкрдиреА рдирд┐рд░реНрднрд░рддрд╛ рдкреНрд░рджрд╛рди рдХрд░реЗрдВ ред рдФрд░ рдЗрд╕ рдмреАрдЪ, рдЕрдкрдиреЗ рд╕рдВрджрд░реНрднреЛрдВ рдХреЛ рдпрдерд╛рд╕рдВрднрд╡ рд╕реНрдерд┐рд░ рд░рдЦреЗрдВред
  • рдФрд░ рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдпрджрд┐ рд╣рдо рдПрдХ рдмреЗрд╣рддрд░ рдПрдкреАрдЖрдИ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдЗрд╕реЗ рд╕реНрд╡рдпрдВ рд╕рдВрднрд╛рд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдФрд░ рдПрдкреАрдЖрдИ рдХреЛ рднрдЧреНрди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрд╣реА рдореЗрд░рд╛ рдкреИрдХреЗрдЬ рд╣реИред

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 рдлрд╝рдВрдХреНрд╢рди рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕ рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдЬреИрд╕реА рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреЗ рд▓рд┐рдП рдХрдИ рднрд╛рд╖рд╛-рд╕реНрддрд░ рдХреЗ рдкреНрд░рд╕реНрддрд╛рд╡ рднреА рд╣реИрдВред рдПрдХ рдФрд░ рдкрд░рд┐рд╡рд╛рдж рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕реЗ 'рд╣рд▓' рдХрд░рдиреЗ рдХреА рдХреЛрдИ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

zpao picture zpao  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

huxiaoqi567 picture huxiaoqi567  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

hnordt picture hnordt  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

framerate picture framerate  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

zpao picture zpao  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ