简体   繁体   中英

Why doesn't spread attributes work with React useState hook

I'm keeping state in a functional component using the useState hook and want to update a single value without having to explicitly set all other attributes, so I thought using the spread operator would work, but it does not!

This is my state:

const [state, setState] = useState({
  data: [],
  currentIndex: 0,
  editMode: false
});

Can someone explain why this doesn't work...

setState({ editMode: value, ...state });

...when this does:

setState({ editMode: value, data: [], currentIndex: 0 });

Whats the difference? Can I use the spread operator or have I misunderstood something?

Here is a CodeSandbox example to demonstrate the issue.

It's all about the order. Think about the following:

 const state = { data: [], currentIndex: 0, editMode: false }; const value = true; const result = { editMode: value, ...state }; const result2 = { editMode: value, data: [], currentIndex: 0 }; const result3 = { ...state, editMode: value }; console.log(result); console.log(result2); console.log(result3);

I hope that helps!

Doing { editMode: value, ...state } is equivelent to:

{                                   {
  editMode: value,                    
  data: [],                           data: [],
  currentIndex: 0,      ------->      currentIndex: 0,
  editMode: false                     editMode: false
}                                   }

As keys cannot be repeated in objects, the last editMode key-value pair overwrites the first, thus removing the first editMode: value . Instead, you can spread first:

{...state, editMode: value}

This will overwrite the editMode in your state with the new object editMode :

{                                   {
  data: [],                           data: [],
  currentIndex: 0,                    currentIndex: 0,
  editMode: false,      ------->      
  editMode: value,                    editMode: value,
}                                   }

Just reverse the order:

setState({ ...state, editMode: value });

Otherwise, you are overwriting editMode 's value with the old value.

要使用useState挂钩更新ObjectuseState使用以下函数语法:

setState(prevState => ({ ...prevState, editMode: value }));

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