Home > OS >  React native Flatlist not re-rendering on state change
React native Flatlist not re-rendering on state change

Time:09-17

I realize there are a lot of questions and answers about this out there but I am fairly new to react native and most of the answers are dealing with React Components and not hooks. In the following example availableInterests is pulled from a firestore database call. Then we loop through the availableInterests so the user can select the their interests from the Flatlist of interests. Everything works great except the FLatlist does not re-render so the button that is used to select currentInterests never shows the change that an interest has been selected. Does anyone see what I am missing here?

const [availableInterests, setAvailableInterests] = useState([]);
const [currentInterests, setCurrentInterests] = useState([]);
    const selectThisInterest = (item) => {
        let myInterests = currentInterests;
        if(myInterests.includes(item.id)) {
          myInterests.pop(item.id);
        } else {
          myInterests.push(item.id);
        }

        setCurrentInterests(myInterests);
      }

  return <View>
    <Text style={styles.text}>Select Your Interests:</Text>
      <FlatList
       data={availableInterests}
       keyExtractor={(item, index) => index.toString()}
       extraData={currentInterests}
       renderItem={({ item, index }) => 
         <View key={item.id}>
           <Text>{item.title}</Text>
           <Text>{item.description}</Text>
           <Image
            source={{ uri: item.icon }}
            style={{ width: 100, height: 100}}
           />
         <TouchableOpacity onPress={() => selectThisInterest(item)}>
           <Text style={styles.buttonText}>{`${currentInterests.includes(item.id) ? 'UnSelect' : 'Select'}`}</Text>
           <Text>{item.id}</Text>
         </TouchableOpacity>
        </View>
      }>
    </FlatList>
</View>

CodePudding user response:

put this state below

const [currentInterests, setCurrentInterests] = useState([]);
const [extra, setExtra] = useState(0);

at the end of your function just put this

    const selectThisInterest = (item) => {
    ....

    setExtra(extra   1)
  }

CodePudding user response:

I think the mistake is in your selectThisInterest function. When you are updating the currentInterests based on previous value, React doesn't recognises such a change because you are simply assigning myInterests with your currentInterests.

What you want to do is to copy that array and assign it to myInteresets and then update your values to the new copied array. Once the calculation are completed on the new myInteresets array, the setCurrentInterests() will re-render the app because now React recognises there is a change in the state.

To copy the array, you can use,

let myInterests = [...currentInterests];

change your selectThisInterest function to reflect this change,

const selectThisInterest = (item) => {
  let myInterests = [...currentInterests];
  if(myInterests.includes(item.id)) {
    myInterests.pop(item.id);
  } else {
    myInterests.push(item.id);
  }
  setCurrentInterests(myInterests);
}
  • Related