0

For a learning and test project, I'm trying to return immutable redux data from reducer because safe data for component. this is my reducer code :

function itemsReducer(state = [], action) {
    switch(action.type) {
        case 'ITEMS':
            return [...action.data]
        default:
            return state
    }
}

And this is my loop code :

<ul>
    {
        this.props.items.map((item) => (
            <li>{item.name.first} {item.name.last}</li>
        ))
    }
</ul>

now every things work right, but after change on props with this method :

change() {
    this.props.items[0] = 'empty'
}

and after loading again items I have this error :

TypeError: Cannot read property 'first' of undefined

Apparently the items did not copy with spread syntax in my reducer and all changes override on that. after executing the data load action at all the index #0 is 'empty'

Thank you

3
  • 1
    How about using Immutable JS? Commented Apr 4, 2019 at 8:57
  • How are you dispatching the action, and what is passed in action.data ? how is the data from the store passed to the component ? your problem can come from many places, please add more details Commented Apr 4, 2019 at 8:57
  • @Oliver I've mapped dispatch and action.data comes from my action Commented Apr 4, 2019 at 8:58

1 Answer 1

4

You shouldn't be mutating the props directly in component, instead dispatch an action that updates the result in reducer

change() {
    this.props.updateItem({first: 'empty'}, 0);
}

and action creator would be

const updateItem = (item, index) => {
   return {type: 'UPDATE_ITEM', item, index}
}

and reducer

function itemsReducer(state = [], action) {
    switch(action.type) {
        case 'ITEMS':
            return [...action.data]
        case 'UPDATE_ITEM': 
            return [...state.slice(0, action.index), {...state[index], ...action.item}, ...state.slice(index+1)];
        default:
            return state
    }
}
Sign up to request clarification or add additional context in comments.

5 Comments

thanks, but that change method was a simple way to change props, of course, that method is not suitable to change data. I was testing immutable variable with that method :-)
@irbgls in order to avoid such issues you can make use of ImmutableJS so that you don't accidently mutate props
Khatari I see, but the props aren't immutable ? I've pass the data with immutable syntax, but why that isn't immutable still ?
using spread syntax to update value doesn't make the props immutable, it just means that while processing ITEMS action you are doing a shallow copy of the state array. Also its a convention that props shouldn't be mutated, but they are mutable like you notice in your case.
Khatari yes, that pass data with spread syntax and that's a copy of my api data. but why after clicking on button to receive data my props doesn't refresh and wants to repeat on old data? because that error message ...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.