#reactjs #react-native #react-context
#reactjs #react-native #реагировать-контекст
Вопрос:
У меня есть компонент, который отображает:
<View>
<SomeContext.Provider value={state}>
{props.children}
</SomeContext.Provider>
</View>
Я не понимаю, как создать метод, доступный следующим образом:
<View>
<SomeContext.Provider>
{(method) =>
<Button
title={"Magic"}
onPress={() => {
method()
}}
></Button>
}
</SomeContext.Provider>
</View>
Комментарии:
1. Эй .. Вы хотите передать метод компоненту Button
2. У вас есть codesandbox , на который мы могли бы взглянуть?
Ответ №1:
Потребительский компонент
Вам нужно использовать контекст через Context.Consumer
, который является прямым потомком соответствующего Provider
. В документах есть достойные примеры, хотя в них сочетаются классовые и функциональные компоненты. Обновление контекста из вложенного компонента
Песочница: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>;
}
Ответ №2:
В документах Context advisorumer на самом деле рассказывается все, что вам нужно знать:
Компонент React, который подписывается на изменения контекста. Это позволяет вам подписаться на контекст внутри функционального компонента.
Требуется функция в качестве дочерней. Функция получает текущее значение контекста и возвращает узел React. Аргумент value, передаваемый функции, будет равен значению prop ближайшего поставщика для этого контекста выше в дереве. Если для этого контекста выше нет поставщика, аргумент value будет равен defaultValue, который был передан в createContext().
Итак, в вашем примере вам нужно передать нужный метод поставщику:
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>
Также важно, чтобы потребительский компонент находился внутри поставщика.