【问题标题】:Setting deeply nested object in Redux reducer not propagating updates to my component在 Redux reducer 中设置深度嵌套的对象不会将更新传播到我的组件
【发布时间】:2019-02-12 00:43:56
【问题描述】:

我试图通过 reducer 在我的 react.js/redux 应用程序中设置一个深度嵌套的对象,但对象更改不会传播到我的组件。我应该如何更新和 mapStateToProps 这样的对象?

我已经尝试...在我的 reducer 中处理我的操作的有效负载,在我的 mapStateToProps 中映射一个更高级别的对象,并将我映射到我的组件道具的对象展平。

我的初始状态:

const initialState = {
    myObject : {
        prop1 : {
            prop2 : {
                array1 : [],
                array2: [],
                array3: []
            }
        }
    }
}

我的减速机:

const app = (state = initialState, action) => {
  switch(action.type) {
    case SET_DATA:
      return {
        ...state,
        myObject: action.payload
      };
  } default:
      return state;
}

export default app;

我的组件:

class Component extends React.PureComponent() {
    render() {
        return (
            {
                JSON.stringify(this.props.componentObject)
            }
        );
    }
}

function mapStateToProps(state) {
    return {
        componentObject: state.myObject
    };
}

export default connect(mapStateToProps)(Component);

更新嵌套对象的动作创建者

export function setData(newDeeplyNestedObject) {
  return {
    type: SET_DATA,
    payload: newDeeplyNestedObject
  };
}

结果是我的组件没有显示 Redux 的状态。 Redux 似乎没有检测到我的组件道具的变化,因此没有更新组件。谁能告诉我如何确保 Redux 在深度嵌套的对象结构发生变化时向我的组件发送更新?

我知道 Redux 对更新进行了浅层比较,但我觉得我的 reducer 中的 JSON.parse(JSON.stringify()) 在这里不是正确的方向。

【问题讨论】:

  • 您的mapStateToProps 不正确,myObjectstate.app 中,但您正在state 中寻找它。你需要做的:componentObject: state.app.myObject

标签: reactjs redux react-redux state


【解决方案1】:

1) 通过以下方式实现商店: import {createStore} from "redux"; export const store = createStore(app) // you pass in your reducer name

2) 在 mapStateToProps 中,访问您的 myObject 状态,如下所示: function mapStateToProps(state){ return{ myObject:state.myObject } };

3) 绑定你的动作调度器:

   import {bindActionCreators} from "redux";
   const mapDispatchToProps = dispatch =>(bindActionCreators({setData}, dispatch));
   //Now we can use the setData action creator as this.props.setData()

4) 同时使用 mapStateToProps 和 mapDispatchToProps 并将其连接到组件:

export default connect(mapStateToProps,mapDispatchToProps)(Component);

5) 假设你在 INITIAL_STATE 中定义了 myObjects,例如:

    myObject : {
        prop1 : {
            prop2 : {
                array1 : [{a:'1'},{b:'2'}],
                array2: [{q:'6'},{w:'4'}],
                array3: [{m:'9'},{n:'0'}]
            }
        }
    }
};

6) 现在您需要使用任何 changeHandlers 或按钮按下 触发您的操作 函数 setData 并传递您想要添加为参数的 newObject。这个想法是传播对象(使用 ... 运算符)并附加您要添加​​的新项目。假设您想在 onClick 事件上触发您的操作并更改 array1 值:

<input type="button" onClick={()=>this.props.setData({...this.props.myObject.prop1.prop2,array1:[{changedA:'21'},{changedB:'32'}]})}/>

这将触发该动作,并且只会更改 array1。同样,您可以对任何嵌套对象执行此操作。 无论你想做什么改变,你都必须传播你的对象,然后追加新的项目

PS: 也将返回值括在标签中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-03
    • 2023-03-09
    • 1970-01-01
    • 2017-08-27
    • 2019-02-26
    • 1970-01-01
    • 2020-10-08
    • 1970-01-01
    相关资源
    最近更新 更多