首页 > 解决方案 > 如何在 Nextjs 布局中使用上下文挂钩

问题描述

我正在用 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>
        )};

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

标签: reactjsreact-hooksnext.jsuse-context

解决方案


问题是您试图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>
  )
};

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


推荐阅读