Реализация функций Redux с использованием контекста и редукторов в React не работает должным образом

#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 отправляется при нажатии кнопки, а глобальное состояние счетчика отображается под кнопкой. Когда я нажимаю на кнопку действия приращения после нажатия на нее несколько раз, я по какой-то причине не определяюсь. Что я здесь делаю не так?

Прежде чем нажать введите описание изображения здесь

После нажатия 3 или 4 раза введите описание изображения здесь

введите описание изображения здесь

Вот моя структура папок на случай, если вы думаете, что я импортирую неправильные материалы

введите описание изображения здесь

Компонент кнопки

 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/… ) имеет все способы, с помощью которых я могу неизменным образом изменять состояние