当redux状态更新时,React componentWillReceiveProps将接收不触发的道具

时间:2017-01-04 07:26:34

标签: reactjs react-native redux react-redux

我有一个持有actions的商店,这些行为假设每次添加新行为时都会循环播放。

我有一个组件MessageListView,它位于名为MessageView的父级中。在我的socketActions.queue数组中添加新操作时,componentWillRecieveProps会被触发,但事实并非如此。

这是我的减速机的样子:

/* Reducer */
const initialState = {
  queue: [{
    type: 'alert',
    action: 'alert',
    completed: false, // Set to true or just delete this object when the action has been completed
    data: {
      message: "the data object dynamically changes based on the type"
    }
  }]
};

export default (state = initialState, action) => {
  switch (action.type) {
  case ADD_ACTION:
    let queue = state.queue
    // action.data['completed'] = false
    queue.push(action.data)
    console.log("Just updated queue", action.data)

    return {
      ...state,
      queue: queue,
      latestAction: new Date()
    }

我的组件连接到商店,如下所示:

function mapStateToProps(state){
  console.log(state, "State inside messagelistview.js")
  return {
    actionsQueue: state.socketActions.queue,
    latestAction: state.socketActions.latestAction
  }
};

const mapDispatchToProps = (dispatch) => {
  return bindActionCreators({ completeAction }, dispatch);
};

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

因此,当我发送新的ADD_ACTION动作时,我的状态更新& redux-logger 打印出新旧状态,告诉我它们是相同的?!。在我更改 latestAction 值后,我不知道为什么会这样做。队列数组。这就是为什么componentWillRecieveProps无法正常工作,但我无法弄清楚为什么状态是一样的?!

4 个答案:

答案 0 :(得分:2)

如果这可以解决任何问题,那么不是100%确定,但我认为你没有正确地将state.queue复制到全新的变量队列中。

我建议做类似的事情:

let queue = state.queue.slice()

......看看有什么变化吗?目前,您的queue变量仍然与state.queue

相同

答案 1 :(得分:2)

您不会在reducer中更改队列标识。试试这段代码:

case ADD_ACTION:
  let queue = state.queue
  // action.data['completed'] = false
  queue.push(action.data)
  console.log("Just updated queue", action.data)

  return {
    ...state,
    queue: [...queue], // <-- here we copy array to get new identity
    latestAction: new Date()
  }

你应该总是浅色复制改变的objets。见http://redux.js.org/docs/Troubleshooting.html#never-mutate-reducer-arguments

答案 2 :(得分:1)

问题在于,当你这样做时,你正在改变你的状态:

                //read the next block
                int k = fread(&buffer, 1, 512, in_pointer);
                if(k != 512)
                {
                        free(filename);
                        return 0;
                }

当您直接改变现有状态时,Redux不会检测到状态差异,也不会通知组件存储已更改。

因此,您可以使用以下选项创建新的let queue = state.queue // action.data['completed'] = false queue.push(action.data) 数组:

queue

或使用ES6糖:

case ADD_ACTION:
  return {
    ...state,
    queue: state.queue.concat(action.data),
    latestAction: new Date()
  }

答案 3 :(得分:1)

连接组件执行浅层检查(===)是否更新状态并仅在检查失败时呈现包装组件。在您的情况下,您正在改变您的队列,导致检查通过相等。

如果您更改缩减器,它将起作用:

state.queue = state.queue.concat(action.data);

或使用ES6语法:

state = { ...state, queue: [...state.queue, action.data] };