简体   繁体   中英

FlatList not re-render in a functional component?

I'm implementing some checklist component when I press to any item in the Flatlist data, I add a toggle property to object and make it true and bassed on it I render a check green icon,

but in this case the Flatlist, not re-rendering, I add extraData prop for Flatlist and pass data to it, but not works well!

here's code

import React, {useState} from 'react';
import {StyleSheet, Text, View, FlatList, TouchableOpacity} from 'react-native';
import Feather from 'react-native-vector-icons/Feather';
import {Theme} from '../utils/colors';

const Data = [
  {
    id: 1,
    first_name: 'Sile',
  },
  {
    id: 2,
    first_name: 'Clementia',
  },
  {
    id: 3,
    first_name: 'Brita',
  },
  {
    id: 4,
    first_name: 'Duke',
  },
  {
    id: 5,
    first_name: 'Hedvig',
  }
];

const BottomModal = () => {
  const [countries, setCountries] = useState(Data);

  const itemSelected = (id) => {
    console.log('current id: ', id);
    let datamanipulat = countries;
    datamanipulat.map((item) => {
      item.toggle = false;
      if (item.id === id) {
        item.toggle = true;
      }
    });
    setCountries(datamanipulat);
    console.log('data after manipulate: ', countries);
  };
  return (
    <View style={styles.container}>
      <FlatList
        ListHeaderComponent={() => (
          <View style={styles.header}>
            <View style={styles.panelHandle} />
          </View>
        )}
        showsVerticalScrollIndicator={false}
        data={countries}
        extraData={countries}
        keyExtractor={(item) => String(item.id)}
        renderItem={({item, index}) => (
          <TouchableOpacity
            key={item.id}
            onPress={() => itemSelected(item.id)}
            style={styles.item}>
            <Text>{`country: ${item.first_name}`}</Text>
            {item.toggle ? (
              <Feather name="check" size={25} color={Theme.PrimaryColor} />
            ) : (
              <Feather name="octagon" size={25} color={Theme.PrimaryColor} />
            )}
          </TouchableOpacity>
        )}
        contentContainerStyle={styles.contentContainerStyle}
      />
      <TouchableOpacity style={styles.doneBtn}>
        <Text style={styles.doneText}>Done</Text>
      </TouchableOpacity>
    </View>
  );
};
export default BottomModal;

Snack example

###Edit

I solve it by adding a flag that changes when I select any item,
and pass it to extraData , If there any other solution, please tell me!

like this

....
  const [itemChecked, setItemChecked] = useState(false);


 const itemSelected = (id) => {
    countries.map((item) => {
      item.toggle = false;
      if (item.id === id) {
        item.toggle = true;
        setItemChecked((prevState) => !prevState);
      }
    });
    setCountries(countries);
  };

...

 <FlatList
       ...
        extraData={itemChecked}
/>

This is happening because you are using the same array. This will work fine if you change your code like below.

  const itemSelected = (id) => {
    console.log('current id: ', id);
    const updated = countries.map((item) => {
      item.toggle = false;
      if (item.id === id) {
        item.toggle = true;
      }
      return item;
    });
    setCountries(updated);
    console.log('data after manipulate ++: ', updated);
  };

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