【问题标题】:useContext working not working with nested componentuseContext 不适用于嵌套组件
【发布时间】:2021-08-07 10:53:43
【问题描述】:

我正在尝试重构应用程序以使用 useContext,但遇到了障碍,无法弄清楚发生了什么。

使用最新版本的一切,运行 Next.js。

事物的结构方式是每个页面都包裹在<Layout> 中,一些 页面也包裹在<Fund> 中,嵌套在<Layout> 下。

我在_app.js 中设置了全局上下文,并传递给Layout 进行渲染。这很好用,我在pages/_app.js 中定义的aTest 上下文变量在Layout 上呈现并显示在所有页面上。

然后,我在components/Fund.js 中设置了特定于基金的上下文,并在pages/fund/index.js(以及随后的其他页面)上加载。

这不起作用。我在 /components/Fund.js 中定义的 anotherTest 上下文变量 not 显示在 /pages/fund/index.js 中,即使那里的 return 语句包装在 <Fund> 组件中(我假设应该保留并传递上下文)。

我想我可能把我的孩子/父母的订单弄混了,因为非工作场景但大脑被炸了。有什么建议吗?

剥离回来,基本代码是:

/components/
   - UserContext.js
   - FundContext.js
   - Layout.js
   - Fund.js

/pages/
   - _app.js
   - index.js
   - /fund/
      - index.js

/components/*Context.js 两个文件中声明的名称是同一个栏:

import { createContext } from 'react';
const FundContext = createContext();
export default FundContext;

import { createContext } from 'react';
const UserContext = createContext();
export default UserContext;

/pages/_app.js我正在做:

import React, { useState } from "react";
import UserContext from '../components/UserContext';
...

function MyApp({ Component, pageProps }) {
   ...
   return (
      <UserContext.Provider value={{
         aTest: "This is a test"
    }}>
      <Component {...pageProps} />
    </UserContext.Provider>
   )
}

export default MyApp

/components/Layout.js我正在做:

import React, { useState, useContext } from "react";
import UserContext from './UserContext';
const Layout = ({children}) => {    

   let {aTest} = useContext(UserContext);

   return (
      <main>
         <h1>{aTest}</h1>
         {children}
      </main>
    )
}

export default Layout

/components/Fund.js我正在做:

import React, { useState, useContext } from "react";
import UserContext from './FundContext';
const Fund = ({children}) => {    

   return (
      <main>
         <h1>{aTest}</h1>
            <FundContext.Provider value={{ anotherTest: "Just another test" }}>
            {children}
         </FundContext.Provider>
      </main>
    )
}

export default Layout

/pages/fund/index.js我正在做:

import React, { useState, useContext } from "react";
import FundContext from '../../components/FundContext';
...

export default function App () { 

   let {anotherTest} = useContext(FundContext);
   
   return (
      <Fund>
         {anotherTest}
      </Fund>
   )
}

【问题讨论】:

    标签: reactjs next.js use-context


    【解决方案1】:

    您的 useContext 挂钩在 /pages/fund/index.js 的全局范围内调用。将钩子移到组件的范围内应该可以解决问题。

    import React, { useState, useContext } from "react";
    import FundContext from '../../components/FundContext';
    ...
    
    export default function App () {
       let {anotherTest} = useContext(FundContext);
     
       return (
          <Fund>
             {anotherTest}
          </Fund>
       )
    

    另外,我在提供的代码中没有看到FundContext.Provider,这意味着对useContext(FundContext) 的调用将无法按预期工作。如果它不存在,请确保将 FundContext 的消费者用它包装起来。

    编辑(OP 更新了问题):

    useContext(FundContext) 在组件树中的FundContext.Provider 上方使用。

      |_App (useContext(FundContext))
         |_Fund
             |_FundContext.Provider
                        |_{anotherTest}
    

    考虑将FundContext.Provider移到App组件上方,或者将类似于以下的组件作为子组件传递给Fund

    const AnotherTest = () => {
      let {anotherTest} = useContext(FundContext);
    
      return (
          <>
             {anotherTest}
          </>
       )
    }
    

    /pages/fund/index.js:

    import React, { useState, useContext } from "react";
    import FundContext from '../../components/FundContext';
    ...
    export default function App () {
       return (
          <Fund>
             <AnotherTest />
          </Fund>
       )
    }
    

    【讨论】:

    • 抱歉我的一些拼写错误,我现在更新了fund.js 以包含FundContext.Provider。我还将useContext 移动到组件内部,但没有修复它。我尝试了控制台日志记录useContext(fundContext) 及其返回undefined
    • 您正在使用组件树中提供程序上方的useContext 挂钩。我将更新答案以反映您的更改
    • 对不起! fund 甚至没有使用useContext 钩子,只是为新上下文FundContext 建立数据,然后将其传递给它的孩子/pages/fund/index.js。示例代码现在应该是正确的(仍然无法正常工作)
    • 现在答案应该是准确的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-20
    • 2021-09-15
    • 2018-12-26
    • 2020-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多