转换路线(页面)时状态重置
state resets when transitioning route(page)
我在这个 CodeSandbox
中重现了这个问题
https://codesandbox.io/s/competent-newton-up21l?file=/pages/index.js
我有两条路线(页数)
/
/car/info
和两个组件
- 页眉
- 汽车输入
我使用上下文来维护状态并将其传递给两个页面。
当我在路线 /car/info
中并使用输入更改状态时,更新后的状态将显示在同一路线(页面)的页眉组件中。
但是当我转到 /
路线(页面)时,状态没有更新。我使用 React 开发工具检查并且上下文没有更新的值。
即使我回到 /car/info
,更新的状态也不在那里。一旦我从 /car/info
过渡到 /
,状态就会回到 intialState .
在沙盒上重新创建相同内容的步骤
- 点击“去添加汽车”
- 在输入框输入车名,点击添加
- 点击“回家”
现在您可以看到您添加的汽车不存在。
更新:正如下面的答案所指出的,我正在更新 localState。
我修复了代码以使用全局状态,但问题仍然存在。
新沙盒:https://codesandbox.io/s/inspiring-pond-mp134?file=/context/cars-context.js
首先,你在添加汽车时在哪里更新状态。
function handleSubmit(e) {
e.preventDefault();
let car = e.target.elements["car"].value;
setCars((prevState) => {
return [...prevState, car];
});
}
上面的代码我是从你的repo复制过来的,只是把新添加的汽车更新到本地状态。这就是它在上下文中不可用的原因。您已经创建了全局上下文但尚未使用它。
你要做的是,
在您的 carInput 中访问上下文 class
const [initialState, dispatch] = useCarContext();
function handleSubmit(e) {
e.preventDefault();
let car = e.target.elements["car"].value;
// Instead of updating to local state,
//upadate your global context using dispatch
// in dispatch pass actionType and the value
dispatch({ type: 'updateNewCar', value: car });
}
同时附上示例上下文实现(您可以根据您的用例进行更改)
import React, { createContext, useContext, useReducer } from "react";
export const initCarContext = () => {
return {
initialState: {
cars: []
},
reducer: function (state, { type, value }) {
switch (type) {
case 'updateNewCar':
state.cars.push(value)
return { ...state };
default:
return state;
}
}
};
};
export const StateContext = createContext();
export const CarStateProvider = ({ reducer, initialState, children }) => (
<StateContext.Provider value={useReducer(reducer, initialState)}>
{children}
</StateContext.Provider>
);
export const useCarContext = () => useContext(StateContext);
https://kentcdodds.com/blog/how-to-use-react-context-effectively/
在 next.js 中进行页面转换时,上下文被卸载。
因此,在 __app.js 页面中包装上下文提供程序可确保它在进行转换时不会被卸载。
我在这个 CodeSandbox
中重现了这个问题https://codesandbox.io/s/competent-newton-up21l?file=/pages/index.js
我有两条路线(页数)
/
/car/info
和两个组件
- 页眉
- 汽车输入
我使用上下文来维护状态并将其传递给两个页面。
当我在路线 /car/info
中并使用输入更改状态时,更新后的状态将显示在同一路线(页面)的页眉组件中。
但是当我转到 /
路线(页面)时,状态没有更新。我使用 React 开发工具检查并且上下文没有更新的值。
即使我回到 /car/info
,更新的状态也不在那里。一旦我从 /car/info
过渡到 /
,状态就会回到 intialState .
在沙盒上重新创建相同内容的步骤
- 点击“去添加汽车”
- 在输入框输入车名,点击添加
- 点击“回家”
现在您可以看到您添加的汽车不存在。
更新:正如下面的答案所指出的,我正在更新 localState。 我修复了代码以使用全局状态,但问题仍然存在。
新沙盒:https://codesandbox.io/s/inspiring-pond-mp134?file=/context/cars-context.js
首先,你在添加汽车时在哪里更新状态。
function handleSubmit(e) {
e.preventDefault();
let car = e.target.elements["car"].value;
setCars((prevState) => {
return [...prevState, car];
});
}
上面的代码我是从你的repo复制过来的,只是把新添加的汽车更新到本地状态。这就是它在上下文中不可用的原因。您已经创建了全局上下文但尚未使用它。
你要做的是,
在您的 carInput 中访问上下文 class
const [initialState, dispatch] = useCarContext();
function handleSubmit(e) {
e.preventDefault();
let car = e.target.elements["car"].value;
// Instead of updating to local state,
//upadate your global context using dispatch
// in dispatch pass actionType and the value
dispatch({ type: 'updateNewCar', value: car });
}
同时附上示例上下文实现(您可以根据您的用例进行更改)
import React, { createContext, useContext, useReducer } from "react";
export const initCarContext = () => {
return {
initialState: {
cars: []
},
reducer: function (state, { type, value }) {
switch (type) {
case 'updateNewCar':
state.cars.push(value)
return { ...state };
default:
return state;
}
}
};
};
export const StateContext = createContext();
export const CarStateProvider = ({ reducer, initialState, children }) => (
<StateContext.Provider value={useReducer(reducer, initialState)}>
{children}
</StateContext.Provider>
);
export const useCarContext = () => useContext(StateContext);
https://kentcdodds.com/blog/how-to-use-react-context-effectively/
在 next.js 中进行页面转换时,上下文被卸载。
因此,在 __app.js 页面中包装上下文提供程序可确保它在进行转换时不会被卸载。