添加到第二次时,基于Redux键的数组不会触发新的道具

时间:2018-06-18 04:03:43

标签: reactjs redux immutability

我正在处理提案和地点。 位置可以包含多个提案

组件被传递一个位置对象(在 passedProps 下面)以显示该位置的所有提议:

<Proposals location={ location } key={location.id}/>

这是我的redux道具:

const mapStateToProps = (state , passedProps) => {
  return {
    proposals : state.propertyProposals[passedProps.location.id]
  };
};

添加新提案时,我希望按位置存储其ID,因此除了存储提案外,我还将其ID存储在由位置ID键入的数组中。

第一个提议添加并刷新了新道具就好了,但是即使第二个提议被成功推送到数组,这也不会触发新的道具,所以它不会刷新&#34; - 如果我离开路线并回来,我会看到新的第二个提案(第一次没有显示)

以下是新提案的PROPOSAL_CREATE操作。

 type :'PROPOSAL_CREATE',
 payload :
{'e7ef104e-19ed-acc8-7db5-8f13839faae3' : { 
    id : 'e7ef104e-19ed-acc8-7db5-8f13839faae3',
    locationId: '41e9c5d8-a520-7e3b-939a-12f784d49712'
    }
}

这是处理它的案例:

case 'PROPOSAL_CREATE':
{
  const proposal = Object.values(action.payload)[0];
  const locationId = proposal.locationId;
  let newState = {...state}
    if (locationId in newState) {
        newState[locationId].push(proposal.id)
    } else {
        newState[locationId] = [proposal.id]
    }

    return newState
}

是否有明显的原因我没有看到第二个条目的组件发生变化?

由于

3 个答案:

答案 0 :(得分:1)

这里有一个问题。您的商店状态不是不可变的。您已使用下面的行制作副本:

let newState = {...state}

这里它确实复制了对象,但它是浅层副本,因此newStatestate中的数组对象具有相同的引用。这就是为什么redux没有识别商店的变化,因此道具不会按顺序更新。

您可以通过以下方法克隆您的州:

let newState = JSON.parse(JSON.stringify(state));

如果你使用jQuery那么:

let newState = $.extend(true, {}, state);

我认为这肯定会解决您的问题。

答案 1 :(得分:0)

根据您的reducer逻辑,我认为您没有指定操作类型。

redux约定之一是基于type属性的动作识别。 我打赌你忘了指定那个属性。

var properAction = {
        type: 'PROPOSAL_CREATE',
        payload: {
            {
                'e7ef104e-19ed-acc8-7db5-8f13839faae3': {
                    id: 'e7ef104e-19ed-acc8-7db5-8f13839faae3',
                    locationId: '41e9c5d8-a520-7e3b-939a-12f784d49712'
                }
            }
        }

我建议你写action creators它会减少你的拼写错误。

干杯!

答案 2 :(得分:0)

2件事:

  1. 我忘记原始对象 Arrays 仍然是引用。所以即使在
  2. 之后

    let newState = {...state}

    newState[locationId] 与...有相同的参考 state[locationId]

    1. 因此,我原来的陈述是改变原始状态,而不是创建一个新状态
    2. 等等 newState[locationId].push(proposal.id)

      需要

      newState[locationId] = state[locationId].concat(proposal.id);
      

      或es6

      newState[locationId] = [ ...state[locationId] , proposal.id ] ;