Сортировка элементов в flatList. Элемент FlatList не обновляется при установке setState () - PullRequest
0 голосов
/ 11 апреля 2020

У меня есть список продуктов, которые отображаются в плоском списке.

Однако у меня есть кнопка, которая переключает отображение этого списка. То есть при значении true он показывает элементы по самой низкой цене, а при значении false - оригинальный список.

Проблема заключается в том, что при первом нажатии кнопки переключения он меняет свое состояние на true и упорядочивает список по цене. Но когда я нажимаю его снова, он меняет состояние на false, но продолжает показывать список, упорядоченный по цене.

Я перепробовал все, чтобы сделать это переключение, но не могу. Может ли кто-нибудь помочь мне, показывая, где это не так?

Мой код:

    import Products from '../../produtos';

    export default () => {
      const [toggleFilter, setToggleFilter] = useState(toggleFilter);

      useEffect(() => {
        setToggleFilter(false)
      }, [])

      const toggleOrdem = () => {
        setToggleFilter(!toggleFilter)
      }

      return (
        <ProductList>

          <Header />
          <Button title="toggle" onPress={toggleOrdem} />

          <FlatList
            keyExtractor={(item, index) => index.toString()}
            showsVerticalScrollIndicator={false}
            data={toggleFilter ? Products.sort((a, b) => a.precoFinal - b.precoFinal) : Products}
            renderItem={({ item }) => <Product data={item} />} />

        </ProductList >
      );
    };

1 Ответ

2 голосов
/ 11 апреля 2020

data = {toggleFilter? Products.sort ((a, b) => a.precoFinal - b.precoFinal): Products}

Сортировка массива приведет к изменению существующего массива. Так что, если toggleFilter истинно, вы постоянно изменяете то, что в Products, то рендеринг это. Когда вы переключаете toggleFilter в false, вы используете Products как есть, но из-за предыдущих рендеров это теперь отсортированный массив.

Вам нужно будет скопировать массив перед сортировкой:

export default () => {
  const [toggleFilter, setToggleFilter] = useState(toggleFilter);

  useEffect(() => {
    setToggleFilter(false);
  }, []);

  const toggleOrdem = () => {
    setToggleFilter(!toggleFilter);
  };

  const sortedArray = toggleFilter
    ? [...Products].sort((a, b) => a.precoFinal - b.precoFinal)
    : Products;

  return (
    <ProductList>
      <Header />
      <Button title="toggle" onPress={toggleOrdem} />

      <FlatList
        keyExtractor={(item, index) => index.toString()}
        showsVerticalScrollIndicator={false}
        data={sortedArray}
        renderItem={({ item }) => <Product data={item} />}
      />
    </ProductList>
  );
};

По соображениям производительности вы можете захотеть запомнить сортировку вместо сортировки каждый раз при рендеринге. Это можно сделать с помощью useMemo следующим образом:

const sortedArray = useMemo(() => {
  return toggleFilter
    ? [...Products].sort((a, b) => a.precoFinal - b.precoFinal)
    : Products;
}, [Products, toggleFilter]);

PS, этот эффект очень странный:

useEffect(() => {
  setToggleFilter(false)
}, [])

Если вы хотите, чтобы переключение начиналось как ложное, удалите эффект и инициализировать состояние с const [toggleFilter, setToggleFilter] = useState(false);

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