如何在 Nextjs 布局中使用Context hook

Car*_*s G 9 reactjs next.js react-hooks use-context

我正在使用 NextJS 构建一个应用程序。我的应用程序显示帖子列表,用户能够从 AZ 或 ZA 对列表进行排序,并在每页显示特定数量的帖子(10,20 等)。当用户单击帖子访问该特定帖子页面,然后返回主列表时,排序和分页首选项将被重置,我设法使用 cookie 保留保留的值,但我想改用useContext()。对于这个应用程序,我有一个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>
        )};
Run Code Online (Sandbox Code Playgroud)

但是当我尝试从我的其中一个页面获取价值时,我得到了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);
Run Code Online (Sandbox Code Playgroud)

还有我的 UseContext.js:

import {createContext} from 'react';

export const SortingContext = createContext(null);

Run Code Online (Sandbox Code Playgroud)

Ale*_*x K 5

问题是您试图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>
  )
};
Run Code Online (Sandbox Code Playgroud)

但是,我的建议可能是将其提升到更高的位置,您可以将其设置在应用程序级别。

  • 我绝对明白你的意思,但我没有带有 nextjs 的 app.js 文件。显然我必须创建一个新的 _app.js 页面才能完成我正在寻找的内容。感谢您为我指明了正确的方向。 (2认同)