【问题标题】:How to useContext hook in Nextjs Layout如何在 Nextjs 布局中使用上下文挂钩
【发布时间】:2020-09-28 23:10:46
【问题描述】:

我正在使用 NextJS 构建一个应用程序。我的应用程序显示帖子列表,用户可以从 A-Z 或 Z-A 对列表进行排序,并在每页显示特定数量的帖子(10、20 等)。当用户单击帖子以访问该特定帖子页面然后返回主列表时,排序和分页首选项被重置,我设法使用 cookie 保留保留的值,但我想使用 @987654321 @ 反而。 对于这个应用程序,我有一个 Layout.js 文件,并认为这是插入我的 Provider 的正确位置,如下所示:

import React, {useState} from 'react';
import Navbar from './Navbar';
import Head from 'next/head';
import {SortingContext} from './UseContext';

const Layout = (props)=> {
  const [value, setValue] = useState('hello');

  return (<SortingContext.Provider value={{value, setValue}}>
            <div>
                <Head>
                  <title>MyApp</title>
                </Head>
                <Navbar/>
                {props.children}
            </div>
            </SortingContext.Provider>
        )};

但是当我尝试从我的一个页面中获取值时,我得到了TypeError: Cannot read property 'value' of null

我在我的应用程序的其他地方使用useContext,所以我知道我可以让它工作。我只是不明白将它放在我的 NextJS 应用程序中的哪个位置,因此即使我访问不同的页面,该值也会保留。

这是我试图打印值的 index.js:

import React, { useState, useEffect, useContext } from 'react';
import withData from '../lib/apollo';
import Layout from '../components/Layout';
import {SortingContext} from '../components/UseContext';
import Footer from '../components/Footer';

const Home = () => {

  const {value, setValue} = useContext(SortingContext);

  return (
    <Layout>
      <div className='main_screen'>
  <h1>{value}</h1>
      </div>
      {siteOptions && <Footer />}
    </Layout>
  )
};

export default withData(Home);

还有我的 UseContext.js:

import {createContext} from 'react';

export const SortingContext = createContext(null);

【问题讨论】:

  • 我们能否看到上下文本身以及您在哪里使用上下文?如果你有一个codeandbox,那会更好
  • 我更新了问题。希望有帮助
  • 确实有帮助!我提供了更详细的答案,如果您需要更清楚的说明,请告诉我!

标签: reactjs react-hooks next.js use-context


【解决方案1】:

问题是您试图在提供上下文的树中更高的useContext。现在,您的提供者在Layout 中,但是,您正尝试在Home 中使用它,这是布局的父级。因此,您可以做几件事,您可以将您的提供者移到Home 之外的更高位置,或者如果您想保持当前的结构,您可以执行以下操作:

const Home = () => {

  const {value, setValue} = useContext(SortingContext);

  return (
    <Layout>
      <SortingContext.Consumer>
         {value =>
            <div className='main_screen'>
              <h1>{value}</h1>
            </div>
            {siteOptions && <Footer />}
         }
      </SortingContext.Consumer>
    </Layout>
  )
};

但是,我的建议可能是将其提高,您可以在应用程序级别使用它。

【讨论】:

  • 我绝对明白你的意思,但我没有带有 nextjs 的 app.js 文件。显然我必须创建一个新的 _app.js 页面才能完成我正在寻找的内容。感谢您将我引向正确的方向。
  • 没错,但我认为这是有道理的,那么如果你有多个上下文,你可以把它们放在那里。
【解决方案2】:

如果你想在整个项目中使用 Context same store 或 Redux,我希望这个建议可以帮助你:

理念: 您必须在项目中创建对象以保存您的分页和/或您的标签,如果用户单击一个帖子并发送回文章,您必须在您的商店中使用您的分页,并且当您刷新页面时此商店可以重置,请执行以下操作:

在 _app.js 中项目根目录的 Provider 顶部创建与此相同,或者您可以在文章组件顶部创建它

<ConfigProvider>
   <your project/>
</ConfigProvider>

在您的项目的 src 中,您可以在目录提供程序上创建并导入此文档中的所有内容 现在创建您的商店:

import { createContext, useContext } from "react";
import React, { useState } from "react";
export const ConfigContext = createContext();
export const ConfigDispatcherContext = createContext();

function ConfigProvider({ children }) {
       const [config, setConfig] = useState({
          type: null,
          page: 1,
          tab: null,
          selectTab: null,
          Filter: {
              sort: "desc",
              type: null,
          },
   });
    return (
    <ConfigContext.Provider value={config}>
        <ConfigDispatcherContext.Provider value={setConfig}>
            {children}
        </ConfigDispatcherContext.Provider>
    </ConfigContext.Provider>
 );
}
function useConfigState() {
   return useContext(ConfigContext);
}
function useConfigSetState() {
  return useContext(ConfigDispatcherContext);
}
export { useConfigState, useConfigSetState };
export default ConfigProvider;

最重要的是,您拥有可以使用同一商店的对象 这意味着 config 和 setConfig 如果你只想要页面,你可以在页面参数上使用 config 变量,现在如何在你的项目中使用它,见下文: 首先将它们从您的目录中导入到旅游组件中,与此相同:

import {
ConfigDispatcherContext,
ConfigContext,
} from "../../providers/ConfigProvider";

现在你在你的函数组件中使用了同样的功能:

    const setConfig = React.useContext(ConfigDispatcherContext);
    const config = React.useContext(ConfigContext);

现在您可以使用以下相同的控制台查看您的商店:

console.log(config)

以及如何在商店中设置分页,您可以使用 setConfig 简单地设置商店,如下所示:

但请注意,如果您的项目要更新您的状态,您必须使用正确的 useEffect

   useEffect(()=> {
      setConfig({
         type: "your type",
         page: your pagination number,
         tab: "your custom tab if you want",
          etc...
       })
    },[your pagination change])

从文章返回后,您可以在组件中使用正确的 useEffect 加载相同的页面

const [currentPage, setCurrentPage] = useState(1);
useEffect(()=>{
    setCorrentPage(config.page)
 },[])

我希望这个建议能对你有所帮助和有用。 祝你好运!

【讨论】:

    猜你喜欢
    • 2021-04-28
    • 2021-02-13
    • 1970-01-01
    • 2021-07-10
    • 1970-01-01
    • 2023-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多