#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
, состояние возвращается к первоначальному состоянию.
Шаги по воссозданию того же самого в изолированной среде
- нажмите «перейти к добавлению автомобиля»
- введите имя автомобиля во ввод и нажмите Добавить
- нажмите «перейти к главному»
Теперь вы можете видеть, что добавленного вами автомобиля там нет.
ОБНОВЛЕНИЕ: как указано в ответах ниже, я обновлял 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 страница гарантирует, что она не будет размонтирована при выполнении перехода.