简体   繁体   English

FlatList 不在功能组件中重新渲染?

[英]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,当我按下 Flatlist 数据中的任何项目时,我正在实现一些清单组件,我向 object 添加了一个切换属性并使其true并基于它我呈现了一个检查绿色图标,

but in this case the Flatlist, not re-rendering, I add extraData prop for Flatlist and pass data to it, but not works well!但在这种情况下,Flatlist,而不是重新渲染,我为 Flatlist 添加了 extraData 道具并将数据传递给它,但效果不佳!

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,我通过添加一个标志来解决它,该标志会在我 select 任何项目时发生变化,
and pass it to extraData , If there any other solution, please tell me!并将其传递给extraData ,如果有其他解决方案,请告诉我!

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM