Update single value in Redux state

Viewed 2675

I have a page with several components on it, one of the components reads redux state. When there some changes occur on the redux object component it reloads, shows the spinner and all the data on the component gets updated. But my task is to update one single value in the redux object state without having to rerender and refresh everything. For instance here is the redux object, which holds an array of objects with some data. I need to update one value state in a certain object let say the last one. But I need to do it without having to update all-state.

state:{
 0:{
  name : 'some name.....',
  surname: 'some surname',
  age: '23',
  phone: '+12345678'
  state: 'ON' 
 },

 1:{
  name : 'some name.....',
  surname: 'some surname',
  age: '23',
  phone: '+12345678'
  state: 'ON' 
 },

 2:{
  name : 'some name.....',
  surname: 'some surname',
  age: '23',
  phone: '+12345678'
  state: 'OFF' <-- I need to update only this one 
 },

}

I have one function in Redux actions that load all these data.

But now I need something like a separate function updateData function which will be updating one value in an existing state object without having to refresh everything.

Is it possible to do so in Redux?

3 Answers

Your state is an object (not an array) of objects. You can't update a single property of your state. You have to supply a new object with the updated values. Study immutability in redux: https://redux.js.org/faq/immutable-data

Try this in your reducer:

const changedVal=state[2];
changedVal.state='ON';
return {...state,changedVal};

You will need to familiarise yourself with how actions and reducers work in Redux but yes, this is most definitely possible.

You can make an UPDATE_DATA action creator that you would call inside your react component(s). And you would have a reducer that will control how the data is processed and state changed.

-edit- As mentioned in the comments, I use "immer" in reducers with Redux. Here's an example of how I've used it for editing and existing item in an array:

case EDIT_ITEM:
      return produce(state, (draft) => {
        const index = findItemIndex(draft, action.payload._id)
        draft[index] = action.payload
      })

So you pass in state and a callback, with draft being the mutable equivalent of the state object.

In short, updating one property isn't possible practically. Of course it can't be done, but it's very difficult. I can explain why.

Let's start with updating an item. This is definitely possible. Suppose you have a redux selector listening to the data, when sending the data over to a component.

  const DisplayOneItem = React.memo(( name, age ) => { ... })

You can see, first the name (and age) is sent to this component, also a React.memo is applied so that only when one of the property is changed, it can then update. But don't get mixed with the following line:

  const DisplayOneItem = React.memo(( item ) => { ... })

The above line takes entire item over, and when you change one property, the item changes as well, therefore no matter what, you will get a new update.

You might wonder what happens if React.memo isn't used? Yes, render all the time. Practically if you change a property, either item or data gets changed entirely. Otherwise how do you notify React there's a change? :)

NOTE: React can't update according to a value change by default. The reason why it updates is because you ask it to, through setState({ ...data }). So now it's the question about how granularity YOU control the dispatch (or render). People might think React is magic in terms of rendering, but actually it only does it upon a request. So now your question is, I ask it to render, but it shouldn't render? Haha, you get the point.

Related