Perform search on State for filtering result react native

Viewed 53

I wanna implement a live Search function on my Redux State which I use in my home page via useSelector. and when user delete the search content original data show up as well. I use filter but the data doesn't affect. how can I achieve that? any help would be appreciated:

const Home = (props) => {

  const companies = useSelector(state => state.companies.availableCompanies); //this is my data
  
  const handleSearch = (e) => {
    companies.filter(el => el.name.includes(e));
    console.log(companies) // here I see my data changes but doesn't affect on UI
  }

  return (
      <SearchBar onChangeText={handleSearch} />
      <View style={styles.cardContainer}>  // here I show data.
        {companies.map((el, index) => {
          return (
           <Card
            key={el.id}
            companyId={el.id}
            companyName={el.name}
            companyImage={el.image}
            companyMainAddress={el.mainAddress}
            companyPhoneNumber={el.telephoneNumber}
            companyDetails={el.details}
            onPress={() => {
              navigation.navigate('CardDetails', {
              id: el.id,
              companyName: el.name,
             });
           }}
          />
         )
       })}
     </View>

3 Answers

Have a try with the below changes

Hope it will work for you.

const Home = (props) => {

  const [searchQuery, setSearchQuery] = useState();
  const [filteredData, setFilteredData] = useState();
  const companies = useSelector(state => state.companies.availableCompanies); //this is my data
  
  const handleSearch = (e) => {
    setSearchQuery(e);
  }

  useEffect(() => {
    if (searchQuery && typeof searchQuery === "string" && searchQuery.length > 0) {
        const searchData = companies.filter(el => el.name.includes(searchQuery));
        setFilteredData([...searchData]);
    } else {
        setFilteredData();
    }
  }, [searchQuery, companies])

  return (
      <SearchBar onChangeText={handleSearch} />
      <View style={styles.cardContainer}> 
        {(filteredData && Array.isArray(filteredData) ? filteredData : companies).map((el, index) => {
          return (
           <Card
            key={el.id}
            companyId={el.id}
            companyName={el.name}
            companyImage={el.image}
            companyMainAddress={el.mainAddress}
            companyPhoneNumber={el.telephoneNumber}
            companyDetails={el.details}
            onPress={() => {
              navigation.navigate('CardDetails', {
              id: el.id,
              companyName: el.name,
             });
           }}
          />
         )
       })}
     </View>

This variable below is a copy of state.companies.availableCompanies that is replaced on every render with the original value from state.companies.availableCompanies.

const companies = useSelector(state => state.companies.availableCompanies); //this is my data

Since you're assigning the result of filter to the copy, and not to the original variable inside the redux store. The results are not reflected there, and every time rerender happens, the Functional Component is called again, making all the code inside this function execute again. So, there is a new variable companies that is not related to the old one.

To actually update the original variable inside redux. You need to create a redux action, and dispatch it.

You need to go back and learn the fundamental concepts of redux before proceeding with this.

Here is the link to the documentation explaining how the data flow works in redux. https://redux.js.org/tutorials/fundamentals/part-2-concepts-data-flow

Related