Morton
Morton

Reputation: 5760

Can not use useState to change array data on function component

I have a list when users click each item will change my array data.

my gender array first data is this:

[
  {optionName: "Man", sex: 1, selected: true},
  {optionName: "Woman", sex: 1, selected: false}
]


const [genderOption, setGenderOption] = useState(gender);

      onItemPress = (item, i) => {
        console.log('print i', i);
        console.log('click genderOption', genderOption);

        genderOption.map((value, index) => {
          genderOption[index].selected = false;
        } );

        console.log('after genderOption', genderOption);

        genderOption[i].selected = true;

        console.log('final genderOption', genderOption);
        // setGenderOption([...genderOption]);

        // setTimeout(() => {
        //   console.log('timeOut !');
        //   setGenderOption([...genderOption]);
        // }, 5000);
      }

      console.log('genderOption', genderOption);

      return (
        // my listView has onPress function trigger onItemPress()
      );

when click index === 0

enter image description here

when click index === 1

enter image description here

It is when I use setTimeout

enter image description here

Upvotes: 0

Views: 153

Answers (2)

Saeed Zhiany
Saeed Zhiany

Reputation: 2141

It's because you try to update the original data items directly within newGender.map iteration.

newGender.map((value, index) => {
  console.log('before', genderOption[index].selected);
  genderOption[index].selected = false; <------ this line is wrong
  console.log('after', genderOption[index].selected);
} );

change it like below, it should be correct

const newGender = genderOption.map((value, index) => ({
  ...value,
  selected = false,
}));

Upvotes: 1

Asaf Aviv
Asaf Aviv

Reputation: 11760

You can easily fix this by mapping over the previous state and setting selected by comparing the indexes

const onItemPress = (item, i) => {
  setGenderOption(prevState => prevState.map((gender, index) => ({
    ...gender,
    selected: i === index,
  }));
};

Upvotes: 1

Related Questions