FlatList не перерисовывается в функциональном компоненте? - PullRequest
0 голосов
/ 10 июля 2020

Я реализую какой-то компонент контрольного списка, когда нажимаю на любой элемент в данных Flatlist, я добавляю свойство toggle к объекту и делаю его true и на его основе я визуализирую зеленый значок галочки,

но в этом случае Flatlist, а не повторный рендеринг, я добавляю опору extraData для Flatlist и передаю в него данные, но работает плохо!

вот код

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;

Пример закуски

### Edit

Я решаю его, добавляя флаг, который меняется при выборе любого элемента, и передайте его на extraData, если есть другое решение, скажите, пожалуйста!

вот так

....
  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}
/>

1 Ответ

1 голос
/ 11 июля 2020

Это происходит потому, что вы используете тот же массив. Это будет нормально работать, если вы измените свой код, как показано ниже.

  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);
  };
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...