0

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

2 Answers 2

1

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,
  }));
};
Sign up to request clarification or add additional context in comments.

1 Comment

It works ! Thanks for your help truly. But why there is a issue in my way ? I think I set a different array to my state. Can you tell me why ? Thanks.
1

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,
}));

9 Comments

Thanks for your help, I must be tired. I correct my code to newGender, the selected result both of them still true.
I comment setGenderOption([...newGender]); the result will be [ {optionName: "Man", sex: 1, selected: false}, {optionName: "Woman", sex: 1, selected: true} ]
So weird, Can you check how time onItemPress being called when pressing one of the items? use console.log and print what is the value of the index i in each call.
then maybe it's because you update the original data directly, I have Updated my answer, you can check if it works or not.
As far as I know, in react (and react-native) compare objects using shallow compare (===) for re-rendering purpose, so when you try to change an item in an array directly, actually the array reference itself will not change, in other word objects must be updated through setState method to making sure their references will be changed. I'm not familiar with hook mechanism in new versions of React but probably it has the same mechanism that causes the strength behavior you saw in your code. I'll update my post if I found any other precise information about that.
|

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.