Reputation: 451
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>
Upvotes: 1
Views: 74
Reputation: 7213
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>
Upvotes: 1
Reputation: 621
You need to use useDispatch()
to get dispatcher and dispatch an action to your reducer with state to update in your handleSearch ()
Something like:
const dispatch = useDispatch();
const handleSearch = (e) => {
dispatch({type:"YOUR_ACTION",payload:companies.filter(el => el.name.includes(e))})
console.log(companies) ;
}
Upvotes: 0
Reputation: 1237
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
Upvotes: 0