Home > other >  how to show initial data if search field is cleared
how to show initial data if search field is cleared

Time:05-02

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}
/>
        

CodePudding user response:

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('');
  • Related