我将Home组件包装为以下布局:

export const DataContext = React.createContext({});

const Layout: React.FunctionComponent = (props) => {
  const data = {title: "abc", description: "def"};

  return (
    <DataContext.Provider value={data}>
        {props.children}
    </DataContext.Provider>
  );
};


我想在Home组件中使用useContext钩子(Hook),但它返回一个空对象:

const Home: React.FunctionComponent = () => {
  const content = React.useContext(DataContext);

  return (
    <Layout>
       // content data goes here
    </Layout>
  );
};


我怀疑这是因为我在包含上下文提供程序的Layout包装器之外定义了上下文变量,因此它回退到我定义的上下文的默认值(一个空对象)。但是,即使我在布局提供程序内部控制台记录了useContext钩子(Hook),它也会返回一个空对象:

const Home: React.FunctionComponent = () => {
  const content = React.useContext(DataContext);

  return (
    <Layout>
      {console.log(React.useContext(DataContext))}
    </Layout>
  );
};


知道为什么吗?

最佳答案

useContext将从最靠近树的value中获取Provider。您的LayoutHome内部,这将使Provider在树中位于其下方。

您可以使Home成为Layout的 child ,而不是使其工作。

示例

const DataContext = React.createContext({});

const Layout = props => {
  const data = { title: "abc", description: "def" };

  return (
    <DataContext.Provider value={data}>{props.children}</DataContext.Provider>
  );
};

const Home = () => {
  const content = React.useContext(DataContext);

  return <div>{JSON.stringify(content)}</div>;
};

function App() {
  return (
    <Layout>
      <Home />
    </Layout>
  );
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="root"></div>

08-17 13:42