0

I'm trying to clean up my warnings, but im facing those dependency warnings.

This is an example, but a lot of useEffect() is facing a similar problem.

Im trying to laod my page calling my fetch api inside useCallback (got samething inside useEffect), but the filter param there is actually a redux state

 useEffect(() => {
    if (checkValidRoute(env.activeSelector.menu, "indicacoes")) {
      dispatch(
        indicationsAction.getIndications(config.page, config.rowsPerPage, config.order, {
          environmentId: env[router.query.ambiente].envId,
          loginId: user.login?.id,
          selectorID: env.activeSelector?.selectorID,
          token: user.login.token,
          details: false,
          filter: {
            status: config.status,
            dateInit: dateFormat(beforeMonth),
            dateEnd: dateFormat(today),
            name: config.name,
            indicatorName: config.indicatorName
          }
        })
      )
    } else {
      router.push(`/${router.query.ambiente}`)
    }
  }, [env, config.status, config.order, dispatch, beforeMonth, config.indicatorName, config.name, config.page, config.rowsPerPage, router, today, user.login?.id, user.login.token])

Those filters has it value associated to an input, i do not want to re-fetch after change my config state, because i need to wait for the user fill all the filter fields, but i need to reload my page if my env change.

I thought about this solution, but it does not work

const filterParams = {
      page: config.page,
      rowsPerPage: config.rowsPerPage,
      order: config.order,
      details: false,
      filter: {
        status: config.status,
        dateInit: dateFormat(beforeMonth),
        dateEnd: dateFormat(today),
        name: config.name,
        indicatorName: config.indicatorName
    }
  }

  const loadPage = useCallback(() => {
    if (checkValidRoute(env.activeSelector.menu, "indicacoes")) {
      dispatch(
        indicationsAction.getIndications({
          environmentId: env[router.query.ambiente].envId,
          loginId: user.login?.id,
          selectorID: env.activeSelector?.selectorID,
          token: user.login.token,
        }, filterParams)
      )
    } else {
      router.push(`/${router.query.ambiente}`)
    }
  }, [dispatch, env, router, user.login?.id, user.login.token, filterParams])

  useEffect(() => {
    loadPage()
  }, [loadPage])

Now I got the following warning: The 'filterParams' object makes the dependencies of useCallback Hook (at line 112) change on every render. Move it inside the useCallback callback. Alternatively, wrap the initialization of 'filterParams' in its own useMemo() Hook.eslintreact-hooks/exhaustive-deps

if add filterParams to useMemo() dependencies samething will happend

// eslint-disable-next-line react-hooks/exhaustive-deps sounds not good ...

There's any solution for this ? I think that I have to change my form to useForm() to get the onChange values then after submit() i set my redux state... but i dont know yet

EDIT: In that case i did understand that we need differente states to control my input state and my request state, they cant be equals. If someone find another solution, i would appreciate (:

EDIT2: Solved by that way:

 const [ filtersState ] = useState(
    {
      page: config.page, 
      rowsPerPage: config.rowsPerPage, 
      order: config.order,
      data: {
        environmentId: env[router.query.ambiente].envId,
        loginId: user.login?.id,
        selectorID: env.activeSelector?.selectorID,
        token: user.login.token,
        details: false,
        filter: {
          status: config.status,
          dateInit: dateFormat(config.dateInit),
          dateEnd: dateFormat(config.dateEnd),
          name: config.name,
          indicatorName: config.indicatorName
        }
      }
    }
  );

  const handleLoadPage = useCallback(() => {
      if (checkValidRoute(env.activeSelector.menu, "indicacoes")) {
        dispatch(indicationsAction.getIndications({
          ...filtersState,
          filters: {
            ...filtersState.filters,
            selectorID: env.activeSelector?.selectorID,
          }
        }))
      } else {
        router.push(`/${router.query.ambiente}`)
      }
    }, [env.activeSelector, filtersState, dispatch, router]
  )

  useEffect(() => {
    handleLoadPage()
  }, [handleLoadPage])

Any other alternatives is appreciate

RenanY.
  • 1
  • 1

1 Answers1

1

The thing here is, if you memoize something, it dependencies(if are in local scope) must be memoized too.

I recommend you read this amazing article about useMemo and useCallback hooks.

To solve your problem you need to wrap filterParams within useMemo hook. And if one of it dependencies are in local scope, for example the dateFormat function, you'll need to wrap it as well.

araujoh
  • 11
  • 1
  • Yeah, the useCallback there was wrong, nice article! the point is, i have to isolate my reducer state from my `useEffect` to avoid side effects. Once all the pages is already created and working with redux in the way that it is, i think i need to change my `useEffect()` params to something else, but working on figure it out – RenanY. Apr 05 '22 at 20:52