转换路线(页面)时状态重置

state resets when transitioning route(page)

我在这个 CodeSandbox

中重现了这个问题

https://codesandbox.io/s/competent-newton-up21l?file=/pages/index.js

我有两条路线(页数)

和两个组件

我使用上下文来维护状态并将其传递给两个页面。

当我在路线 /car/info 中并使用输入更改状态时,更新后的状态将显示在同一路线(页面)的页眉组件中。

但是当我转到 / 路线(页面)时,状态没有更新。我使用 React 开发工具检查并且上下文没有更新的值。

即使我回到 /car/info ,更新的状态也不在那里。一旦我从 /car/info 过渡到 /,状态就会回到 intialState .

在沙盒上重新创建相同内容的步骤

  1. 点击“去添加汽车”
  2. 在输入框输入车名,点击添加
  3. 点击“回家”

现在您可以看到您添加的汽车不存在。

更新:正如下面的答案所指出的,我正在更新 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 页面中包装上下文提供程序可确保它在进行转换时不会被卸载。