Почему добавление дополнительного состояния помогает обновить другое состояние? - PullRequest
0 голосов
/ 12 июля 2020

Вот полный код:

import * as React from 'react';
import { View, ScrollView, StyleSheet } from 'react-native';
import {
  Appbar,
  Searchbar,
  List,
  BottomNavigation,
  Text,
  Button,
} from 'react-native-paper';

const AccordionCollection = ({ data }) => {
  var bookLists = data.map(function (item) {
    var items = [];
    for (let i = 0; i < item.total; i++) {
      items.push(
        <Button mode="contained" style={{ margin: 10 }}>
          {i}
        </Button>
      );
    }
    return (
      <List.Accordion
        title={item.title}
        left={(props) => <List.Icon {...props} icon="alpha-g-circle" />}>
        <View
          style={{
            flexDirection: 'row',
            flexWrap: 'wrap',
            alignItems: 'flex-start',
            backgroundColor: 'white',
          }}>
          {items}
        </View>
      </List.Accordion>
    );
  });
  return bookLists;
};

const MusicRoute = () => {
  const DATA = [
    {
      key: 1,
      title: 'Zain dishes',
      total: 21,
    },
    {
      key: 2,
      title: 'Sides',
      total: 32,
    },
    {
      key: 3,
      title: 'Drinks',
      total: 53,
    },
    {
      key: 4,
      title: 'Aesserts',
      total: 14,
    },
  ];
  const [data, setData] = React.useState(DATA);
  const [searchQuery, setSearchQuery] = React.useState('');
  const [sortAZ, setSortAZ] = React.useState(false);

  const onChangeSearch = (query) => {
    setSearchQuery(query);
    const newData = DATA.filter((item) => {
      return item.title.toLowerCase().includes(query.toLowerCase());
    });
    setData(newData);
  };

  const goSortAZ = () => {
    setSortAZ(true);
    setData(
      data.sort((a, b) => (a.title > b.title ? 1 : b.title > a.title ? -1 : 0))
    );
  };

  const goUnSort = () => {
    setSortAZ(false);
    setData(DATA);
  };
  return (
    <View>
      <Appbar.Header style={styles.appBar}>
        <Appbar.BackAction onPress={() => null} />

        <Searchbar
          placeholder="Search"
          onChangeText={onChangeSearch}
          value={searchQuery}
          style={styles.searchBar}
        />

        <Appbar.Action
          icon="sort-alphabetical-ascending"
          onPress={() => goSortAZ()}
        />
        <Appbar.Action icon="library-shelves" onPress={() => goUnSort()} />
      </Appbar.Header>
      <ScrollView>
        <List.Section title="Accordions">
          <AccordionCollection data={data} />
        </List.Section>
      </ScrollView>
    </View>
  );
};

const AlbumsRoute = () => <Text>Albums</Text>;

const MyComponent = () => {
  const [index, setIndex] = React.useState(0);
  const [routes] = React.useState([
    { key: 'music', title: 'Music', icon: 'queue-music' },
    { key: 'albums', title: 'Albums', icon: 'album' },
  ]);

  const renderScene = BottomNavigation.SceneMap({
    music: MusicRoute,
    albums: AlbumsRoute,
  });

  return (
    <BottomNavigation
      navigationState={{ index, routes }}
      onIndexChange={setIndex}
      renderScene={renderScene}
    />
  );
};

const styles = StyleSheet.create({
  appBar: {
    justifyContent: 'space-between',
  },
  searchBar: {
    width: '60%',
    shadowOpacity: 0,
    borderRadius: 10,
    backgroundColor: '#e4e3e3',
  },
});

export default MyComponent;

Expo Snack Link

Есть два странных механизма.

Первый

Если я удалю sortAZ(true) из goSortAZ() и sortAZ(false) из goUnSort(), состояние data перестанет обновляться после того, как вы нажмете кнопки (1) сортировка и (2) отсортировать больше, чем три раза.

Второй

Если я удалю массив DATA за пределами компонента, кнопки сортировки и сортировки не работают / не обновляются.

Если Эти два я не удаляю, могу отсортировать и отсортировать список. Я чувствую, что код беспорядочный, хотя он выполняет функцию.

Мои вопросы:

  • Почему добавление дополнительного состояния (sortAZ) помогает обновить другое состояние (данные)?

1 Ответ

0 голосов
/ 12 июля 2020

Просто полностью удалите переменную sortAZ (нет необходимости использовать ее, если вы каким-то образом не хотите иметь статус loading, но, поскольку вы не делаете HTTP-запросы, это не обязательно) и замените goSortAZ следующим:

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

  const goSortAZ = () => {
    setData(
      [...data].sort((a, b) => (a.title > b.title ? 1 : b.title > a.title ? -1 : 0))
    );
  };

Я бы посоветовал использовать ту же технику и для метода unSort.

...