0

我有这些文件:

numPadHandler(我的 reducer)、configureStore(我的商店)、TestRedux(我的组件,尝试使用商店)和我的应用程序文件。

减速机:

    // store/reducers/numpadReducers/numpadHandler
    
    const initialState = { valueNumPad: "1" }
    
    function numpadHandler(state = initialState, action) {
        let nextState;
        
        switch(action.type) {
            case 'ADD_DIGIT':
                nextState = state;
                nextState.valueNumPad = nextState.valueNumPad + action.value;
    
                console.log("reducer new state : " + state.valueNumPad); 
                return nextState;
    
            default:
                return state;
        }
    }
    
    export default numpadHandler;

店铺 :

    // store/configureStore

    import { createStore } from 'redux';
    import numpadHandler from './reducers/numpadReducers/numpadHandler';
    
    export default createStore(numpadHandler);

零件 :


    // components/TestRedux
    
    import React, { useState } from "react";
    import { connect } from 'react-redux';
    import Button from './Button';
    
    const TestRedux = (props) => {
        const handleClick = () => {
            console.log("props value numpad : " + props.valueNumPad);
    
            const action = { type: "ADD_DIGIT", value: 5 }
            props.dispatch(action);
        }
        
        return (
            <div>
                <Button onClick={handleClick} />
            </div>
        );
    }
    
    const mapStateToProps = (state) => {
        console.log("state : " + state.valueNumPad);
        return state
    }
    
    export default connect(mapStateToProps)(TestRedux);

应用程序 :

//...
render() {
        return (
            <Provider store={ Store }>
                <TestRedux />
            </Provider>
       );
}

我不明白为什么当我点击按钮时,reducer 的状态正在改变,但函数 mapStateToProps 没有被再次调用。

页面加载后有我的控制台输出:

state : 1

一键后:

props value numpad : 1
reducer new state : 15

两次点击后:

props value numpad : 1
reducer new state : 155

单击 2 次后完成控制台输出:

state : 1
props value numpad : 1
reducer new state : 15
props value numpad : 1
reducer new state : 155

所以你可以看到动作正在发生,reducer 状态正在更新,但组件端没有更新!

你能解释一下为什么吗?

已解决:基于 TLadd 响应的答案:

我的减速器代码是错误的,这是编码的好方法:


    case 'ADD_DIGIT':
      const nextState = { 
        ...state, 
        valueNumPad: state.valueNumPad + action.value
      };
      return nextState

4

1 回答 1

2

问题出在减速器中:

case 'ADD_DIGIT':
  nextState = state;
  nextState.valueNumPad = nextState.valueNumPad + action.value;
  console.log("reducer new state : " + state.valueNumPad); 
  return nextState;

Redux 假设所有状态更改都被不可变地处理。此选择允许它在决定您的应用程序的哪些部分需要重新渲染以响应正在调度的操作时使用浅层相等检查。在上述 reducer 案例中,您将 state 分配给 nextState 并将新值直接分配给nextState.valueNumPad. 即使nextState是新的引用,它仍然引用原始状态,结果是原始状态的突变。

正确的做法是:

case 'ADD_DIGIT':
  const nextState = { 
    ...state, 
    valueNumPad: state.valueNumPad + action.value
  };
  return nextState

在这种情况下,我正在使用扩展符号制作状态副本...state并覆盖该valueNumPad副本中的值。返回nextState的是一个新对象,我根本没有改变旧state对象。

于 2020-10-12T16:55:29.777 回答