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