简体   繁体   中英

Redux reducer not changing the store's state properly

I am building a small application for adopting pets that has a form to add and delete pets from the adoption list.

API

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

Function that creates the form

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>);
}

My reducer addPet looks like this

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

The AddPet component is a button that dispatches the action ADD_PET that creates a new form field with the inputs name and breed at the bottom of the form. This is done by pushing an empty { breed: '', name: '' } to the pets array for the selected category.

The problem is when I try to add a pet more than once.

When a pet is added the first time, it creates an empty form with the breed and name with empty fields. Now if new pets are added, the form will contain the same name and breed fields of the field added previously.

example of the unwanted behaviour:

1) form gets loaded with the data from the API as place holder. [expected]

2) user clicks on AddPet button which creates a new empty form with name and breed without placeholders. [expected]

3) user writes the pet name and breed on the newly created form and clicks the AddPet component. [expected]

4) a new form with same name and breed as in step 3). [unexpected]

Something is happening with the state[payload.keys].faqs.push({ breed: '', name '' }) from the reducer.

push is not an immutable operation. you are changing the array itself. So it has the same state and previous state.

You have to create a copy of previous array, and push into this new copy the new item.

For example:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM