我正在用NextJS构建一个应用程序。我的应用程序显示帖子列表,用户可以从 A-Z 或 Z-A 对列表进行排序,并显示每页特定数量的帖子(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 应用程序中放置它的位置,因此即使我访问其他页面,该值也会保留。
这是我的索引.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);
和我的使用上下文.js:
import {createContext} from 'react';
export const SortingContext = createContext(null);
问题是您正在尝试在提供上下文的树中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>
)
};
但是,我的建议可能是将其提升到更高的位置,您可以在应用程序级别使用它。
如果你想使用上下文相同的存储或Redux整个项目,我希望这个建议可以帮助你:
哲学: 您必须在项目中创建对象以保存您的分页和/或您的选项卡,如果用户单击一个帖子并发送回文章,您必须在您的商店中使用您的分页,并且当您刷新页面时可以重置此商店,请同样这样做:
在项目根目录的提供程序顶部创建,_app.js相同,或者您可以在文章组件的顶部创建它
<ConfigProvider>
<your project/>
</ConfigProvider>
在 src 中,您可以在 Directori 提供程序上创建并导入本文档中的所有内容 现在创建您的商店,如下所示:
import { createContext, useContext } from "react";
import React, { useState } from "react";
export const ConfigContext = 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, setConfig]}>
{children}
</ConfigContext.Provider>
);
}
export default ConfigProvider;
在对象上,您可以使用相同的商店 这意味着config和setConfig,如果你只想要一个页面,你可以在config变量上只使用页面上的参数,现在如何在你的项目中使用它,见下文: 首先,从 Tour 组件中的目录中导入它们,如下所示:
import {
ConfigContext,
} from "../../providers/ConfigProvider";
现在,您可以在函数组件中使用与以下内容相同的功能:
const [config, setConfig] = 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(()=>{
setCorrectPage(config.page)
},[])