Home > Software design >  Why useEffect return the previous state of value?
Why useEffect return the previous state of value?

Time:12-29

I am using the useEffect hook to make some function execute each time the string searchTerms is changing

useEffect(() => {
    analyticsService?.logEvent(ANALYTICS_EVENTS.SEARCH_COMPLETED, {      
      total_results: data?.hits.total.value,
      error_message: null,
    });
  }, [searchTerms]);

So this log event occurs each time searchTerms is changing, but the problem is that it returns the previous value of the property total_results. In addition, I don't need logEvent when the searchTerms is null(usually in the beginning it happens).

Is it possible to solve these problems and how? Btw here is the function looks like this:

const SearchResults: FunctionComponent<SearchResultsProps> = ({
      refinement,
      searchTerms,
      currentPage,
    }) => {
      const { formatMessage } = useIntl();
      const { analyticsService } = useContainerProps();
      const shouldRender = searchTerms.length > 0;
      const { data, isFetching, isLoading } = usePagedQuery({
        refinement,
        terms: searchTerms,
        count: recordsPerPage,
        offset: (currentPage - 1) * recordsPerPage,
        queryEnabled: shouldRender,
      });
      const [isVar, setVar] = useState(true)
      const [isSearched, setIsSearched] = useState(isVar ? true : false)
      const smth = isSearched;
    
      useEffect(() => {
        analyticsService?.logEvent(ANALYTICS_EVENTS.SEARCH_COMPLETED, {      
          total_results: data?.hits.total.value,
          error_message: null,
        });
      }, [searchTerms]);
    ...

CodePudding user response:

  1. In order to get the "latest" state value, you should include data as one of the dependency, for it to "react" to the latest state:
useEffect(() => {
  analyticsService?.logEvent(ANALYTICS_EVENTS.SEARCH_COMPLETED, {
    total_results: data?.hits.total.value,
    error_message: null,
  });
}, [searchTerms, data]); // <- include every changing variables
  1. In order to skip certain operation, you can add a check to determine should it be called or not:
useEffect(() => {
  if (searchTerms) { // <- a simple check
    analyticsService?.logEvent(ANALYTICS_EVENTS.SEARCH_COMPLETED, {
      total_results: data?.hits.total.value,
      error_message: null,
    });
  }
}, [searchTerms, data]);

Dependencies is one of the "Gotcha", and it's best to always include every variable as it's dependency.

  • Related