[React] Handle Deep Object Comparison in React's useEffect hook with the useRef Hook

When you smart component need to handle server request, it would be good to make sure it won't send multi same request to the backend. For example a search input component

The way to prevent it is by check whether the search query is the same as previous one. if it is then stop server request

The second argument to React's useEffect hook is an array of dependencies for your useEffect callback. When any value in that array changes, the effect callback is re-run. But the variables object we're passing to that array is created during render, so our effect will be re-run every render even if the shape of the object is the same. So let's solve this by doing our own equality check from within the effect callback and useEffect hooks..

function Query({query, variables, normalize = data => data, children}) {
  const client = useContext(GitHub.Context)
  const [state, setState] = useReducer(
    (state, newState) => ({...state, ...newState}),
    {
      loaded: false,
      fetching: false,
      data: null,
      error: null,
    },
  )

  useEffect(() => {
    if (isEqual(previousInputs.current, [query, variables])) {
      return
    }
    setState({fetching: true})
    client
      .request(query, variables)
      .then(res =>
        setState({
          data: normalize(res),
          error: null,
          loaded: true,
          fetching: false,
        }),
      )
      .catch(error =>
        setState({
          error,
          data: null,
          loaded: false,
          fetching: false,
        }),
      )
  })

  const previousInputs = useRef()
  useEffect(() => {
    previousInputs.current = [query, variables]
  })

  return children(state)
}

猜你喜欢

转载自www.cnblogs.com/Answer1215/p/12805033.html