Skip to content
This repository has been archived by the owner on Oct 1, 2024. It is now read-only.

Switch hook on useMountedRef from useEffect to useLayoutEffect to support React 17 #1964

Merged
merged 4 commits into from
Jul 6, 2021

Conversation

lucabezerra
Copy link
Contributor

@lucabezerra lucabezerra commented Jun 30, 2021

Description

useEffect's cleanup function is no longer synchronous, so we switched to useLayoutEffect to preserve the behaviour of useMountedRef in React 17+.

Source: https://reactjs.org/blog/2020/08/10/react-v17-rc.html#effect-cleanup-timing

Fixes #1959

Checklist

  • I have added a changelog entry, prefixed by the type of change noted above (Documentation fix and Test update does not need a changelog as we do not publish new version)

Tophat Instructions

On package.json, upgrade React and ReactDOM to the following:

    "react": "17.0.2",
    "react-dom": "17.0.2",

And the resolutions to:

    "@types/react": "17.0.11",
    "@types/react-dom": "17.0.8"

Then run yarn && yarn test react-hooks. The tests should pass!

@lucabezerra lucabezerra requested a review from a team June 30, 2021 18:22
Copy link
Contributor

@marutypes marutypes left a comment

Choose a reason for hiding this comment

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

Checks out to me, but probably we want someone else to also review since I helped make it :P

@BPScott
Copy link
Member

BPScott commented Jun 30, 2021

IIRC recall useLayoutEffect doesn't work on the server-side. If we make this change then I think we're going get a lot of logspam or errors about that.

#1813 seems to be a related issue where useEffect being async is a pain (though that was an issue in the mount rather than unmount phase). Perhaps that might offer some inspiration

Perhaps just using useIsomorphicLayoutEffect instead of useLayoutEffect is enough.

@marutypes
Copy link
Contributor

@BPScott I'm not sure we need useMountedRef to work on the server, since "mounted" doesn't have a super clear meaning there. We could use the isomorphic version anyway I guess though.

@BPScott
Copy link
Member

BPScott commented Jul 6, 2021

@TheMallen yep I agree this doesn't make much sense on the server as useLayoutEffect/useEffect doesn't do anything. however if you call useLayoutEffect on the server React emits the following warning to the console (while useEffect keeps quiet):

Warning: useLayoutEffect does nothing on the server, because its effect cannot be encoded into the server renderer's output format. This will lead to a mismatch between the initial, non-hydrated UI and the intended UI. To avoid this, useLayoutEffect should only be used in components that render exclusively on the client. See https://fb.me/react-uselayouteffect-ssr for common fixes

My "it should work on the server" claim was really "it should not trigger loads of those warning logs for consumers" - which means we should either use useEffect or a noop function on the server side

@BPScott
Copy link
Member

BPScott commented Jul 6, 2021

Gave this a tick :shipit: . I'd love to see a test for this but I'm not sure how that would work, so that's not an issue for now.

@marutypes
Copy link
Contributor

@BPScott the existing tests fail without this changeset, so we're covered imo

@BPScott
Copy link
Member

BPScott commented Jul 6, 2021

Oh perfect! in that case ignore me :)

@lucabezerra lucabezerra merged commit 4e9a11e into main Jul 6, 2021
@lucabezerra lucabezerra deleted the fix-uselayouteffect branch July 6, 2021 18:52
@shopify-shipit shopify-shipit bot temporarily deployed to production July 13, 2021 21:24 Inactive
@shopify-shipit shopify-shipit bot temporarily deployed to gem August 30, 2021 18:42 Inactive
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

React-hooks should work with React 17
4 participants