Redux reducer不能正确改变商店的状态

时间:2016-12-17 19:47:54

标签: reactjs redux

我正在建立一个小型应用程序来收养宠物,这些宠物的形式可以从采用清单中添加和删除宠物。

API

$ dates='20[01][0-9][01][0-9][0-3][0-9]'
$ printf '%s\n' $dates/ | awk '$1>d{d=$1} END{print d}'
20161120/

创建表单的函数

[
   {category: 'dog', pets: [{breed: 'chihuahua', name: 'bar' }, ....]},
   {category: 'cat', pets: [{breed: 'tobby', name: 'foo'}, ....]},
   ....
]

我的reducer addPet看起来像这样

export default function petFieldset({
 petGroups, addPet, deletePet, deleteCategory,
 nameInputChange, breedInputChange, categoryInputChange
}) {

const categoryField = Object.keys(petGroups).map((keys) => (
    <Fieldset
        title={'Pet Category'}
        button={<Delete onClick={deleteCategory.bind(this, { keys })} />}
        key={keys}
    >
        <CategoryComponent
            petGroup={petGroups[keys]}
            deletePet={deletePet}
            categoryKey={keys}
            nameInputChange={nameInputChange}
            breedInputChange={breedInputChange}
            categoryInputChange={categoryInputChange}
        />
        <br />
        <AddPet onClick={addPet.bind(this, { keys })} />
    </Fieldset>
));

return (<div>{ categoryField }</div>);
}

AddPet 组件是一个按钮,用于调度创建新表单字段的操作[ADD_PET]: (state, { payload }) => { state[payload.keys].pets.push({ breed: '', name '' }); return { ...state }; }, ,其中输入ADD_PETname位于底部形成。这是通过将空breed推送到所选类别的pets数组来完成的。

问题是当我尝试不止一次添加宠物时。

第一次添加宠物时,它会创建一个空表单,其中{ breed: '', name: '' }breed为空字段。现在,如果添加了新宠物,表单将包含之前添加的字段的namename字段。

不受欢迎行为的示例:

1)表单从作为占位符的API加载数据。 [预期]

2)用户点击breed按钮,创建一个新的空表单,其中AddPetname没有占位符。 [预期]

3)用户在新创建的表单上编写宠物名称和品种,然后单击breed组件。 [预期]

4)与步骤3中的AddPetname相同的新表单。 [意外]

来自reducer的breed正在发生一些事情。

1 个答案:

答案 0 :(得分:3)

push不是一个不可变的操作。你正在改变数组本身。所以它具有相同的状态和先前的状态。

您必须创建以前数组的副本,并将新项目推送到此新副本。

例如:

[ADD_PET]: (state, { payload }) => {
    let pets = [...state[payload.keys].pets];
    pets.push({ breed: '', name '' });
    return { ...state, payload.keys: pets };
},