我有一个呈现的组件:
<View>
<SomeContext.Provider value={state}>
{props.children}
</SomeContext.Provider>
</View>
我不明白如何创建可通过以下方式访问的方法:
<View>
<SomeContext.Provider>
{(method) =>
<Button
title={"Magic"}
onPress={() => {
method()
}}
></Button>
}
</SomeContext.Provider>
</View>
答案 0 :(得分:2)
消费组件
您需要通过Context.Consumer
使用上下文,该上下文是相关Provider
的直接后代。尽管混合了基于类和功能的组件,但这些文档还是有不错的示例。 Updating Context from a Nested Component
沙盒: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挂钩
useContext
挂钩也可用,并且可能提供了更熟悉的模式。上下文的使用者仍然需要是提供者的后代,但是可以通过钩子而不是通过使用者组件来访问它。
沙盒: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>;
}
答案 1 :(得分:1)
Context counsumer docs实际上会告诉您所有您需要了解的内容:
订阅上下文更改的React组件。这样,您可以在功能组件中订阅上下文。
需要一个功能作为孩子。 该函数接收当前上下文值并返回一个React节点。传递给函数的value参数将等于树中以上上下文的最接近Provider的值prop。如果上面的上下文没有提供者,则value参数将等于传递给createContext()的defaultValue。
因此,在您的示例中,您需要将所需的方法传递给提供程序:
const method = () => {};
<View>
<SomeContext.Provider value={{ method }}>
{props.children}
</SomeContext.Provider>
</View>
然后在Consumer中,您可以这样称呼它:
<View>
<SomeContext.Consumer>
// using destructuring here,
// so its ({ method }) instead of (method)
{({ method }) =>
<Button
title={"Magic"}
onPress={() => method()} />
}
</SomeContext.Consumer>
</View>
此外,重要的是消费者组件位于提供程序内部。