简体   繁体   中英

Filter and search both option in a list react/react-native

I have a list that has an option for searching and filtering. Example


const users = [
  {
    id: '54545',
    name: 'john wick',
    status: 'ACTIVE',
  },
  {
    id: '54546',
    name: 'john wick2',
    status: 'DELETED',
  },
  {
    id: '54547',
    name: 'john wick3',
    status: 'SUSPENDED',
  },
];

Search is performed on the basis of name and filtering is performed on the basis of status Now there is a function named getUsers which returns the data used to render the list item

// returns filteredUsers or searchedUsers if they exists otherwise returns the Users
const getUsers = () => filteredUsers || searchedUsers || users

.
.
.
<List data={getUsers()} />

So, basically the filteredUsers has priority over the searchedUsers Whenever a user performs the filter operation filteredUsers are shown. Now there are 2 constraints.

  1. User should be able to search and after searching, can apply the filters(this is handled by the above-mentioned code of getUsers() as the filter has priority over the search, therefore, filtered users will be rendered)
  2. The user can apply filtered and after that, he performs a search and the search result will be shown(This can't be performed by the above-mentioned code of getUsers() as in this case there are both filteredUserts and searchedUsers and filter have the priority over the search, therefore, searched users will not be rendered).

How can I implement point 2?

You should make it a two steps process rather than one.

const filteredUsers = getFilteredUsers(users);
const searchedUsers = getSearchedUsers(filteredUsers);

in getSearchedUsers if search.length==0 return original users

else filter the required according to search text.

Use State to handle filtering and search

snak: https://snack.expo.io/bOrYw9mSF

check this code

import * as React from 'react';
import { Text, View, StyleSheet, ScrollView, TextInput, Button } from 'react-native';
import Constants from 'expo-constants';

const USERS = [
  {
    id: '54545',
    name: 'john wick',
    status: 'ACTIVE',
  },
  {
    id: '54546',
    name: 'john wick2',
    status: 'DELETED',
  },
  {
    id: '54547',
    name: 'john wick3',
    status: 'SUSPENDED',
  },
  {
    id: '32434',
    name: 'Spiderman',
    status: 'ACTIVE',
  },
];
export default function App() {
  const [state, setState] = React.useState({
    users: USERS,
    seacrhText: '',
    filterBy: null,
  });

  React.useEffect(() => {
    if (state.filterBy) {
    setState({ ...state, users: filterBy(state.users) });
    } else {
      if (state.seacrhText) {
        setState({
          ...state,
          users: serachusers(USERS)
        })
      } else {
        setState({
        ...state, 
        users: USERS
      })
      }
    }
  }, [state.filterBy]);

  React.useEffect(() => {
    if (state.seacrhText) {
    setState({ ...state, users: serachusers(state.users) });
    } else {
      if (state.filterBy) {
        setState({
          ...state,
          users: filterBy(USERS)
        })
      } else {
        setState({
        ...state, 
        users: USERS
      })
      }
    }
  }, [state.seacrhText]);

  const filterBy = (users) => {
    if (state.filterBy) {
      return users.filter(({ status }) => status === state.filterBy);
    } else {
      return users;
    }
  };

  const serachusers = (users) => {
    if (state.seacrhText) {
      return users.filter((user) =>
        user.name.toLocaleLowerCase().includes(state.seacrhText)
      );
    } else {
      return users;
    }
  };

  return (
    <View style={styles.container}>
      <Text>Filter By</Text>
      <View style={styles.fiters}>
        {['ACTIVE', 'DELETED', 'SUSPENDED'].map((val) => (
          <TouchableOpacity
            style={{ marginRight: 10 }}
            onPress={() => {
              setState({
                ...state,
                filterBy: state.filterBy === val ? null : val,
              });
            }}>
            <CheckBox value={state.filterBy === val} />
            <Text>{val}</Text>
          </TouchableOpacity>
        ))}
      </View>
      <TextInput
        style={{
          alignSelf: 'stretch',
          height: 50,
          borderWidth: 0.4,
          paddingHorizontal: 10,
          borderColor: '#ccc',
        }}
        onChangeText={(seacrhText) => {
          setState({
            ...state,
            seacrhText,
          });
        }}
        placeholder="Search wiht name"
      />
      {/*<Button
        title="Search"
        onPress={() => {
          setState({
            ...state,
            users: serachusers(state.seacrhText),
          });
        }}
      />*/}
      <ScrollView>
        {state.users.map(({ name, status }, key) => (
          <View
            style={{
              alignSelf: 'stretch',
              flexDirection: 'row',
              alignItems: 'center',
              marginVertical: 10,
            }}>
            <Text>{name}</Text>
            <Text style={{ marginLeft: 20, fontSize: 10 }}>{status}</Text>
          </View>
        ))}
      </ScrollView>
    </View>
  );
}

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