如何在上下文中创建子组件可以访问的方法?

时间:2020-08-26 22:28:58

标签: reactjs react-native react-context

我有一个呈现的组件:

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

我不明白如何创建可通过以下方式访问的方法:

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

2 个答案:

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

此外,重要的是消费者组件位于提供程序内部。