#reactjs #redux #react-hooks
Вопрос:
Поэтому я пытаюсь реализовать функциональность redux, используя только крючки реакции, как показано в следующих ссылках https://codeburst.io/global-state-with-react-hooks-and-context-api-87019cc4f2cf amp; https://www.sitepoint.com/replace-redux-react-hooks-context-api/ Но я почему-то не могу заставить его работать должным образом. Я пытаюсь реализовать базовую настройку, в которой действие DO_ACTION отправляется при нажатии кнопки, а глобальное состояние счетчика отображается под кнопкой. Когда я нажимаю на кнопку действия приращения после нажатия на нее несколько раз, я по какой-то причине не определяюсь. Что я здесь делаю не так?
Вот моя структура папок на случай, если вы думаете, что я импортирую неправильные материалы
Компонент кнопки
import './Button.css';
import React, {useEffect, useContext} from 'react';
import {Context} from '../../store/Store.js';
const Button = ( props ) => {
const [state, dispatch] = useContext(Context);
const incrementAction = () => {
dispatch({
type:'DO_ACTION',
payload: 1
})
console.log(state.number);
};
return (
<div>
<button onClick={() => incrementAction()}>Display Number!!!!</button>
<div>{state.number}</div>
</div>
)
};
export default Button
вот мой редуктор
const Reducer = (state, action) => {
switch (action.type) {
case 'DO_ACTION':
return state action.payload
}
};
export default Reducer;
Вот мой глобальный магазин и HOC
import React, {createContext, useReducer} from "react";
import Reducer from './Reducer';
const initialState = {
number: 5
};
const Store = ({children}) => {
const [state, dispatch] = useReducer(Reducer, initialState);
return (
<Context.Provider value={[state, dispatch]}>
{children}
</Context.Provider>
)
};
export const Context = createContext(initialState);
export default Store;
И вот мой основной компонент приложения, который упакован в магазин, чтобы он был доступен во всем моем приложении
import Store from './store/Store.js';
import Button from './components/Button/Button.js';
const App = () => {
return (
<div>
<Store>
<Button />
<OtherComponents /> //a bunch of other components go here like title, paging etc
</Store>
</div>
);
}
export default App;
Комментарии:
1. Я понял, что в коде для редуктора я возвращаю состояние действие. полезная нагрузка, в то время как на самом деле должно быть возвращаемое состояние.число действие. полезная нагрузка. Я исправил эту проблему, но я все еще не определился, и номер не отображается под кнопкой
Ответ №1:
Вам нужно возвращать весь (клонированный) объект состояния из вашей функции редуктора, а не только свойство, которое вы хотите обновить. Вы также должны убедиться, что у вас есть вариант по умолчанию:
const Reducer = (state, action) => {
switch (action.type) {
case 'DO_ACTION':
return {
number: state.number action.payload
}
default:
return state;
}
};
export default Reducer;
Если у вас есть более одного свойства в вашем объекте состояния, вы должны не забыть клонировать в него все остальные свойства (например {...state, number: state.number action.payload}
).
Комментарии:
1. Ах, я вижу, я вижу. К. спасибо, что заставил его работать. Примечание для себя на будущее: ВСЕГДА НЕИЗМЕННО МЕНЯЙТЕ СОСТОЯНИЕ! И этот веб-сайт ( medium.com/@housecor/… ) имеет все способы, с помощью которых я могу неизменным образом изменять состояние