Qwertie
Qwertie

Reputation: 6493

React hooks loses state when storing an object

I have crated state in my react function component using

  console.log('reset');
  const [val, setVal] = useState(props.data.bulk_notification.overdue_notification.active);
  const [state, setState] = useState({
    isOverdueActive: props.data.bulk_notification.overdue_notification.active,
    isUpcomingActive: props.data.bulk_notification.upcoming_notification.active,
  });

  console.log(state);
  console.log('val', val);

state is how I would like to access things and val is the only way I have found to work.

After loading the component I see

reset

Object { isOverdueActive: false, isUpcomingActive: false }

val false

These values have been set as expected from props. Then after changing state with an onClick event I see

reset 
Object { isOverdueActive: true, isUpcomingActive: false }
val true

reset 
Object { isOverdueActive: false, isUpcomingActive: false }
val true

The code setting the state onClick is

  setState({ ...state, isOverdueActive: !notification.active });
  setVal(!notification.active);

It seems that only the state which was a simple bool was persisted across component rerender while the object was reset using the props passed down. Is there some special behavior for objects? Should objects be used in state with react hooks?

Upvotes: 0

Views: 967

Answers (1)

Jason
Jason

Reputation: 367

When your new state is dependent on previous state, use should use a callback in setter. (setState in this case)

instead of...
setState({ ...state, isOverdueActive: !notification.active });

I would use
setState(previousState => {
  const newState = { ...previousState, isOverdueActive: !notification.active }
  return newState
  );

When you provide a function to your setter(s), it receives the current(or previous) state as an argument.

And also agreeing with the comments above, showing more of your code would help.

Upvotes: 2

Related Questions