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