состояние сбрасывается при переходе маршрута (страницы)

#reactjs #next.js #react-context

#reactjs #next.js #реагировать-контекст

Вопрос:

я воссоздал проблему в этом CodeSandbox

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

у меня есть два маршрута (страницы)

  • /
  • /car/info

и два компонента

  • Заголовок
  • CarInput

я использовал контекст для поддержания состояния и передачи его на обе страницы.

когда я на маршруте /car/info и меняю состояние с помощью ввода, обновленное состояние отображается в компоненте заголовка того же маршрута (страницы).

Но когда я перехожу на / маршрут (страницу), состояние не обновляется. я проверил с помощью инструментов react dev, и контекст не имеет обновленных значений.

Даже когда я возвращаюсь /car/info , обновленного состояния там тоже нет. Как только я перехожу в / состояние from /car/info , состояние возвращается к первоначальному состоянию.

Шаги по воссозданию того же самого в изолированной среде

  1. нажмите «перейти к добавлению автомобиля»
  2. введите имя автомобиля во ввод и нажмите Добавить
  3. нажмите «перейти к главному»

Теперь вы можете видеть, что добавленного вами автомобиля там нет.

ОБНОВЛЕНИЕ: как указано в ответах ниже, я обновлял LocalState . я исправил код для использования глобального состояния, но проблема не устранена.

Новая изолированная среда: https://codesandbox.io/s/inspiring-pond-mp134?file=/context/cars-context.js

Ответ №1:

Прежде всего, где вы обновляете состояние при добавлении автомобиля.

   function handleSubmit(e) {
    e.preventDefault();
    let car = e.target.elements["car"].value;
    setCars((prevState) => {
      return [...prevState, car];
    });
  }
  

Приведенный выше код я скопировал из вашего репозитория, обновив только недавно добавленный car до локального состояния. Именно по этой причине он недоступен в контексте. Вы создали глобальный контекст, но не используете его.

что вам нужно сделать, это,

Доступ к контексту в вашем классе carInput

 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/

Комментарии:

1. спасибо за ответ! я обновил код, но проблема не устранена . codesandbox.io/s/inspiring-pond-mp134?file=/context /…

2. Я предлагаю вам перейти по ссылке, указанной в ответе. Это даст больше ясности в отношении контекста.

Ответ №2:

при выполнении перехода страницы в next.js , контекст размонтируется.

Итак, обертывание поставщика контекста в __app.js страница гарантирует, что она не будет размонтирована при выполнении перехода.