Skip to content

fix: stop infinite rerenders by removing query from useEffect deps#88

Merged
amcgee merged 3 commits intomasterfrom
fix/render-loop
Aug 25, 2019
Merged

fix: stop infinite rerenders by removing query from useEffect deps#88
amcgee merged 3 commits intomasterfrom
fix/render-loop

Conversation

@amcgee
Copy link
Copy Markdown
Contributor

@amcgee amcgee commented Aug 24, 2019

IMPORTANT FIX

A (sort of) bug was introduced in #34 - we started re-fetching whenever the query changed, but since many queries are object literals constructed within the render loop, their reference identity would actually change and cause an infinite loop of re-renders and re-fetches. @Mohammer5 noticed this in the new maintenance app.

The true "correct" solution might be to do a deep equality check on the query, but I think this is a good solution for now - we don't list query as a dep of useEffect, even though it technically is. This means nothing will happen if the query is updated after the hook is first run by the render method, which should be fine.

@amcgee amcgee requested review from Mohammer5 and varl August 24, 2019 20:16
@amcgee
Copy link
Copy Markdown
Contributor Author

amcgee commented Aug 24, 2019

Side note: our code style enforcement is too good - this breaks an eslint rule, so before I explicitly disabled that rule for this line cli-style silently undid my change precommit and turned the commit into a no-op

@amcgee amcgee merged commit ac9fa28 into master Aug 25, 2019
@amcgee amcgee deleted the fix/render-loop branch August 25, 2019 10:54
dhis2-bot pushed a commit that referenced this pull request Aug 25, 2019
## [1.5.1](v1.5.0...v1.5.1) (2019-08-25)

### Bug Fixes

* stop infinite rerenders by removing query from useEffect deps ([#88](#88)) ([ac9fa28](ac9fa28))
@dhis2-bot
Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 1.5.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

// Cleanup inflight requests
return abort
}, [context, query, refetchCount])
}, [context, refetchCount]) // eslint-disable-line react-hooks/exhaustive-deps
Copy link
Copy Markdown

@SferaDev SferaDev Aug 25, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@amcgee Query should be mutable or immutable by design?

Instead of a deep equality check, a ref could be used instead.

If mutable it just holds initial value inside and if mutable it updates the ref with actual value as a side effect.

And in the dependency array you can now safely use the ref as it won't change its object reference.

function Example(query) {
  const request = useRef(query);
  // If immutable just remove the side effect that updates
  useEffect(() => {
    request.current = query;
  });
} 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants