'how to show initial data if search field is cleared
Initially, useEffect is used to get data from the server and list it in a table. The records are paginated. When a user begins to type I make a debounced request to the server to search the database. When the data is returned I am setting the state and the table is updated to show the results. However, when the user clears the text field I want to show the initial list again as if they hadn't typed anything. It seems like this is what happens but it isn't loading the initial list but rather hitting the search endpoint again and returning all results. Do I need to run the initial useEffect again somehow instead?
What would be the best approach based on the below?
const [searchTerm, setSearchTerm] = useState();
const [data, setData] = useState([]);
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
const ourRequest = axios.CancelToken.source();
const getBookings = async () => {
setIsLoading(true);
const response = await axios.get(
`${process.env.NEXT_PUBLIC_API_BASE_URL}/api/v1/all?page=${pageNumber}&limit=20`, {
cancelToken: ourRequest.token,
}
);
setData(response.data);
setNumberOfPages(response.data.totalPages);
setIsLoading(false);
};
getBookings();
return () => {
ourRequest.cancel();
};
}, [pageNumber]);
// when user types
const handleChange = (event) => {
const {
value
} = event.target;
setSearchTerm(value);
handleSearch(value);
};
// search
const handleSearch = useCallback(
debounce(async (searchTerm) => {
const response = await axios.post(
`${process.env.NEXT_PUBLIC_API_BASE_URL}/api/v1/search`, {
searchTerm: searchTerm
}
);
setData(response.data);
}, 500),
[]
);
<Form.Control
type="text"
placeholder="Search..."
value={searchTerm}
onChange={handleChange}
/>
Solution 1:[1]
You can move getBookings function out of useEffect for the re-usage. Whenever your search input field is empty, you just fetch data again from it.
const [searchTerm, setSearchTerm] = useState();
const [data, setData] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const requestToken = useRef()
const getBookings = async () => {
setIsLoading(true);
const response = await axios.get(
`${process.env.NEXT_PUBLIC_API_BASE_URL}/api/v1/all?page=${pageNumber}&limit=20`, {
cancelToken: requestToken.current.token,
}
);
setData(response.data);
setNumberOfPages(response.data.totalPages);
setIsLoading(false);
};
useEffect(() => {
requestToken.current = axios.CancelToken.source();
getBookings();
return () => {
requestToken.current.cancel();
};
}, [pageNumber]);
// when user types
const handleChange = (event) => {
const {
value
} = event.target;
setSearchTerm(value);
handleSearch(value);
};
// search
const handleSearch = useCallback(
debounce(async (searchTerm) => {
//if search input field is empty
if(!searchTerm) {
getBookings();
return; //stop other logic
}
const response = await axios.post(
`${process.env.NEXT_PUBLIC_API_BASE_URL}/api/v1/search`, {
searchTerm: searchTerm
}
);
setData(response.data);
}, 500),
[]
);
<Form.Control
type="text"
placeholder="Search..."
value={searchTerm}
onChange={handleChange}
/>
About the warning you get, your value is moving from an undefined value to a defined value. In your case, it's possibly from searchTerm state.
You should set an empty string as a default value for searchTerm
const [searchTerm, setSearchTerm] = useState('');
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
