Я уже довольно давно пытаюсь решить проблему, описанную ниже, но так и не смог понять, в чем дело.
Я отправляю действие из своего компонента, и состояние обновляется, что подтверждается его регистрацией в действии. Однако когда я пытаюсь получить доступ к значению состояния сразу после отправки действия, оно все равно показывает начальное значение состояния.
Пожалуйста, взгляните на приведенный ниже код.
сущностьSlice.js
export const entitySlice = createSlice({
name: 'entity',
initialState,
reducers: {
setEntity: (state, action) => {
state = action.payload;
console.info(state.entityAttributes);
},
},
});
export const { setEntity } = entitySlice.actions;
export default entitySlice.reducer;
Редактор.jsx
const EntityEditor = () => {
const effectRan = useRef(false);
const [searchParams] = useSearchParams();
const dispatch = useDispatch();
const entityData1 = useSelector((state) => state.entity);
useEffect(() => {
if (!effectRan.current) {
effectRan.current = true;
getEntityData();
}
});
const getEntityData = () => {
entityOperations.getEntity(searchParams.get("PK_Entity")).then(function (response) {
dispatch(setEntity(response));
console.info(entityData1);
},
function (error) {
console.info(error);
}
);
};
}
Я получаю правильный ответ от API, и значение состояния меняется, как и ожидалось, когда я проверяю его с помощью console.info(state.entityAttributes);
. Однако когда я проверяю данные с помощью console.info(entityData1);
, я все равно вижу начальное значение состояния, а не обновленное. Будем очень признательны за любые подсказки о том, как это исправить.
Спасибо
🤔 А знаете ли вы, что...
С помощью JavaScript можно валидировать данные на стороне клиента, что улучшает пользовательский опыт.
Как я сказал в своем комментарии, проблема связана с тем, что JavaScript фиксирует значения в хранилище Redux во время последнего рендеринга, что означает, что он не получает обновленные значения. Я также был неправ в том, что пропустил, что вы не возвращаете новое состояние или объект полезной нагрузки, что означает, что он не установлен. Вот исправление, которое я сделал, обратите внимание, что я сделал его на TypeScript, потому что это имеет больше смысла, сдержанно предвзято, и я использовал некоторые макетные данные, так как не хотел запускать для него какой-то случайный бэкэнд.
App.tsx — ваш Editor.jsx.
import { useRef, useEffect } from 'react';
import { getMockData } from './MockData';
import { useDispatch } from 'react-redux';
import { setEntity } from './Redux/EntitySlice';
import store from './Redux/store';
const App = () => {
const effectRan = useRef(false);
const dispatch = useDispatch();
useEffect(() => {
if (!effectRan.current) {
effectRan.current = true;
getEntityData();
}
});
const getEntityData = () => {
getMockData().then(
function (response) {
dispatch(setEntity(response));
console.info(store.getState().entity);
},
function (error) {
console.info(error);
}
);
};
return <div></div>;
};
export default App;
EntitySlice.ts — вашentitySlice.js.
import { PayloadAction, createSlice } from '@reduxjs/toolkit';
import { card } from '../MockData';
const initialState: card[] = [];
export const entitySlice = createSlice({
name: 'entity',
initialState,
reducers: {
setEntity: (_, action: PayloadAction<card[]>) => {
return action.payload;
},
},
});
export const { setEntity } = entitySlice.actions;
export default entitySlice.reducer;
С этой настройкой у меня все сработало. Надеюсь, это поможет, в противном случае просто оставьте комментарий, а я еще раз посмотрю и отредактирую свой ответ :-)
В вашем коде есть одна проблема и одно недоразумение.
Основная проблема заключается в том, что вы переназначаете переменную state
в своем редукторе. Это то, что Redux Toolkit не может обнаружить (он может обнаруживать только мутации переменной state
), вместо этого вам нужно вернуть новое состояние (как описано здесь и здесь).
// state = action.payload; // Incorrect
return action.payload; // Correct
Недоразумение заключается в том, что следующий фрагмент кода будет регистрировать новые данные:
dispatch(setEntity(response));
console.info(entityData1);
Это невозможно. В Javascript вызовы функций (например, вызов dispatch
) не могут переназначать локальные переменные вызывающей функции, поэтому entityData1
не может быть другим сразу после dispatch
. Однако произойдет следующее: React запланирует повторную отрисовку компонента, а это означает, что ваш компонент будет вызван еще раз, на этот раз с новыми данными. Поэтому вам следует поместить console.info(entityData1)
прямо в тело компонента, если вы хотите, чтобы он изменился.