The search functionality works but when I clear the input value, the complete list does not show up. I am using filter
method for it, I am not understanding how can I get the full list back.
//search the subscriber in the list
function SearchBar() {
const { subscriber, setsubscriber } = useContext(Context)
const handleSearch = (e) => {
e.preventDefault()
const text = e.target.value;
const filteredUser = subscriber.filter((user) => {
if (user.name.includes(text)) {
return user.name
}
})
setsubscriber(filteredUser)
}
return (
<div className='searchBar'><TextField
id="input1"
label="Search User Name"
onChange={(e) => handleSearch(e)}
/>
</div>
)
}
//list of subscriber
export default function ShowSubscriber() {
const { subscriber } = useContext(Context)
const subscribers = subscriber && subscriber.map &&
subscriber.map((item, i) =>
(
<div style={{ display: "flex", marginTop: "20px" }} key={i}>
<span style={{ fontSize: "25px", marginLeft: "20px", marginRight: "20px" }}>{item.name} {item.subscribedToChannel}</span>
<EditSubscriber />
<DeleteSubscriber /></div>))
return subscribers;
}
Don't mutate your source of truth, e.g. the subscriber
value/state being provided by the Context
. Filtering is a reducing action, and once elements are removed from the source array they can't be brought back without either re-fetching all the data, or caching a separate copy of it or keeping track of what was removed. This would be extraneous unnecessary work and logic.
I suggest storing the filtering value in to the Context
and provide either an already filtered subscriber
value, or provide both subscriber
and the filter value to consumers for them to apply and compute the derived "state" value.
Examples:
Compute and provide derived filtered subscribers array
Context.jsx
const [search, setSearch] = React.useState("");
...
const filteredSubscribers = React.useMemo(() => {
return (subscriber ?? []).filter(
item => item.name.toLowerCase().includes(search)
);
}, [search, subscriber]);
...
function SearchBar() {
const { search, setSearch } = useContext(Context);
const handleSearch = (e) => {
e.preventDefault()
setSearch(e.target.value.toLowerCase());
}
return (
<div className='searchBar'>
<TextField
id="input1"
label="Search User Name"
value={search}
onChange={handleSearch}
/>
</div>
)
}
export default function ShowSubscriber() {
const { filteredSubscribers } = useContext(Context);
return filteredSubscribers
.map((item, i) => (
<div style={{ display: "flex", marginTop: "20px" }} key={i}>
<span
style={{
fontSize: "25px",
marginLeft: "20px",
marginRight: "20px"
}}
>
{item.name} {item.subscribedToChannel}
</span>
<EditSubscriber />
<DeleteSubscriber />
</div>
));
}
Provide both subscriber
and search
to consumers
Context.jsx
const [search, setSearch] = React.useState("");
...
function SearchBar() {
const { search, setSearch } = useContext(Context);
const handleSearch = (e) => {
e.preventDefault()
setSearch(e.target.value.toLowerCase());
}
return (
<div className='searchBar'>
<TextField
id="input1"
label="Search User Name"
value={search}
onChange={handleSearch}
/>
</div>
)
}
export default function ShowSubscriber() {
const { search, subscriber } = useContext(Context);
return subscriber
?.filter(item => item.name.toLowerCase().includes(search))
.map((item, i) => (
<div style={{ display: "flex", marginTop: "20px" }} key={i}>
<span
style={{
fontSize: "25px",
marginLeft: "20px",
marginRight: "20px"
}}
>
{item.name} {item.subscribedToChannel}
</span>
<EditSubscriber />
<DeleteSubscriber />
</div>
));
}