Reducer 未正确更新状态

问题描述 投票:0回答:1
// rootReducer.js

import { combineReducers } from "redux";
import counterReducer from "./counter.reducer";

const rootReducer = combineReducers({
    counter: counterReducer
})

export default rootReducer
// counterReducer.js

import { DECREMENT_COUNTER, INCREMENT_COUNTER } from "../Constants";
import initialState from "../initialState";

const counterReducer = (state = initialState, action) => {
    switch (action.type) {
        case INCREMENT_COUNTER: {
            return {
                ...state,
                counter: state.counter + 1
            }
        }
        
        case DECREMENT_COUNTER:
            return {
                ...state,
                counter: state.counter - 1
            }

        default:
            return state
    }
}

export default counterReducer
// App.js
import React from 'react';
import './App.css';
import { useDispatch, useSelector } from 'react-redux';
import { decrementCounter, incrementCounter } from './actions/counter.action';

function App() {
  const selector = useSelector(state => state)
  console.log(selector)
  const dispatch = useDispatch()
  return (
    <div>
      <h1>Counter: {selector.counter}</h1>
      <button onClick={() => dispatch(incrementCounter())}>Increment</button>
      <button onClick={() => dispatch(decrementCounter())}>Decrement</button>
    </div>
  );
}

export default App;

// index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { Provider } from 'react-redux';
import store from './store';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <Provider store={store}>
    <App />
  </Provider>
);

reportWebVitals();

// store.js

import { configureStore } from "@reduxjs/toolkit";
import initialState from "./initialState";
import rootReducer from "./reducers/root.reducer";

const store = configureStore({
    reducer: rootReducer,
    preloadedState: initialState
})

export default store

因此,我尝试使用递增和递减按钮来实现计数器,但是当我单击递增或递减按钮时,它会显示错误说明
Objects are not valid as a React child (found: object with keys {counter}).

我尝试过控制台记录状态,我发现最初我的状态看起来像

counter: 0

但是当我点击递增或递减按钮时状态变为

counter: {
    counter: NaN
}

我无法弄清楚为什么会发生这种情况。我希望有人能帮助我

谢谢!!

reactjs react-redux store redux-reducers redux-actions
1个回答
0
投票

如果状态最初是

counter: 0
,那么我怀疑
initialState
counterReducer
实际上只是类似
const initialState = 0;
的东西。看来问题是你的
counterReducer
函数正在注入嵌套的
counter
属性。

state.counter
未定义,当您加/减时,它会产生
NaN
,然后对
NaN
的所有进一步数学运算都是
NaN

const state = 0;

console.log({ state, "state.counter + 1": state.counter + 1 });

更新

counterReducer
递增/递减情况,以添加或减去
state
(即计数器值)。

const counterReducer = (state = initialState, action) => {
  switch (action.type) {
    case INCREMENT_COUNTER:
      return state + 1;
        
    case DECREMENT_COUNTER:
      return state - 1;

    default:
      return state;
  }
}

在用户界面中,您需要选择要订阅的特定状态。 不要编写返回整个状态的选择器函数,例如不要使用

useSelector(state => state);

function App() {
  const counter = useSelector(state => state.counter);
  const dispatch = useDispatch();

  return (
    <div>
      <h1>Counter: {counter}</h1>
      <button onClick={() => dispatch(incrementCounter())}>
        Increment
      </button>
      <button onClick={() => dispatch(decrementCounter())}>
        Decrement
      </button>
    </div>
  );
}
© www.soinside.com 2019 - 2024. All rights reserved.