How can create a method in context that can be accessible by child components?

故事扮演 提交于 2021-01-29 20:36:50

问题


I have a component that renders:

<View>
   <SomeContext.Provider value={state}>
        {props.children}
   </SomeContext.Provider>
</View>

I don't understand how to create a method accessible in the following way:

<View>
   <SomeContext.Provider>
        {(method) =>  
                <Button
                   title={"Magic"}
                   onPress={() => {
                     method()
                   }}
                 ></Button>
        }
   </SomeContext.Provider>
</View>

回答1:


Consumer Component

You need to consume a context through a Context.Consumer that is a direct descendent of the the relevant Provider. The docs have decent examples, though they mix class-based and functional components. Updating Context from a Nested Component

Sandbox: https://codesandbox.io/s/react-context-consumer-passing-method-to-nested-child-forked-u0bi8

const initData = {
  data: { a: "Text from Context", b: "2" },
  method: () => {
    console.log("Method called.");
  }
};

const SomeContext = React.createContext();

export default function App() {
  return (
    <SomeContext.Provider value={initData}>
      <Content />
    </SomeContext.Provider>
  );
}

function Content() {
  return (
    <div>
      <SomeButton />
    </div>
  );
}

function SomeButton() {
  return (
    <SomeContext.Consumer>
      {({ data, method }) => <button onClick={method}>{data.a}</button>}
    </SomeContext.Consumer>
  );
}


useContext Hook

The useContext hook is also available, and possibly provides a more familiar pattern. The Consumer of the context still needs to be a descendant of the Provider, but it is accessed via an hook rather than through a Consumer component.

Sandbox: https://codesandbox.io/s/react-context-passing-method-to-nested-child-1fcno

const initData = {
  data: { a: "Text from Context", b: "2" },
  method: () => {
    console.log("Method called.");
  }
};

const SomeContext = React.createContext();

export default function App() {
  return (
    <SomeContext.Provider value={initData}>
      <Toolbar />
    </SomeContext.Provider>
  );
}

function Toolbar(props) {
  return (
    <div>
      <SomeButton />
    </div>
  );
}

function SomeButton() {
  const { data, method } = React.useContext(SomeContext);
  return <button onClick={method}>{data.a}</button>;
}



回答2:


The Context counsumer docs actually tells you everything you need to know:

A React component that subscribes to context changes. This lets you subscribe to a context within a function component.

Requires a function as a child. The function receives the current context value and returns a React node. The value argument passed to the function will be equal to the value prop of the closest Provider for this context above in the tree. If there is no Provider for this context above, the value argument will be equal to the defaultValue that was passed to createContext().

So, in your example you need to pass the method you want to the provider:

const method = () => {};

<View>
  <SomeContext.Provider value={{ method }}>
    {props.children}
  </SomeContext.Provider>
</View>

And then in the Consumer you can call it like this:

<View>
  <SomeContext.Consumer>
    // using destructuring here,
    // so its ({ method }) instead of (method)
    {({ method }) =>  
      <Button
        title={"Magic"}
        onPress={() => method()} />
    }
  </SomeContext.Consumer>
</View>

Also, it's important that the consumer component is inside the provider.



来源:https://stackoverflow.com/questions/63606592/how-can-create-a-method-in-context-that-can-be-accessible-by-child-components

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!