Skip to content

Add React 18 compatibility - #655

Merged
zerobias merged 19 commits into
effector:masterfrom
AlexandrHoroshih:react-18
May 15, 2022
Merged

Add React 18 compatibility#655
zerobias merged 19 commits into
effector:masterfrom
AlexandrHoroshih:react-18

Conversation

@AlexandrHoroshih

@AlexandrHoroshih AlexandrHoroshih commented Apr 9, 2022

Copy link
Copy Markdown
Member

Closes #643

Changelog

  • updated react and react-dom to latest 18.x.x version
  • added backward testing mode for react-17 version - changes for react-18 compatibility should not break usage of effector with react-17
  • move effector-react implementation to official useSyncExternalStore for integration with react-18 and shim of useSyncExternalStore for react-17
  • fixed memoization for fn in useStoreMap - previous implementation prevented re-computation of fn during render, if both store state and keys were not changed. New implementation must keep this behaviour (test: 6790129)
  • add more tests based on examples from issue useStoreMap is broken with React 18. #643 and check, if new implementation fixes them

@netlify

netlify Bot commented Apr 9, 2022

Copy link
Copy Markdown

‼️ Deploy request for effector-docs rejected.

Name Link
🔨 Latest commit 7afe4ab

Comment thread src/react/apiBase.ts Outdated
<div>
<p>{prefix}</p>
<p>{text}</p>
</div>

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

See comment for 004da3e

const user = createStore('guest')
const friends = createStore<string[]>([])
const user = createStore('guest', {sid: 'user'})
const friends = createStore<string[]>([], {sid: 'friends'})

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

See comment for a2e04ee

Comment thread src/react/apiBase.ts
}, [store, scope])
const subscribe = (cb: () => void) => createWatch(store, cb, scope)
const read = () => stateReader(store, scope)
const currentValue = useSyncExternalStore(subscribe, read, read)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Third argument is getServerSnapshot - in case of effector there is no difference with client version
https://reactjs.org/docs/hooks-reference.html#usesyncexternalstore

Comment thread src/react/apiBase.ts Outdated
@sergeysova

Copy link
Copy Markdown
Member

@AlexandrHoroshih What about to upgrade react-17 to react-18?

@AlexandrHoroshih

AlexandrHoroshih commented Apr 19, 2022

Copy link
Copy Markdown
Member Author

@sergeysova It is upgraded in the repo 🤔

It is implementation of effector-react was changed to official react package and the effector-react is allowed to be used with react of >=16.8.0 <19.0.0 version

@sergeysova

sergeysova commented Apr 19, 2022

Copy link
Copy Markdown
Member

@AlexandrHoroshih Oh, yeah. I see that react package is upgraded to 18, but react-18 is on 17. Ok, makes sense. Thank you!

https://github.com/AlexandrHoroshih/effector/blob/react-18/package.json#L96-L99

@sergeysova sergeysova added the effector-react effector-react package label Apr 27, 2022
keep old fixture for backward compatibility tests
effector-react must be updated to work correctly with react-18, but at the same time it should not break react-17 compatiblity
due to substitution of react-18 to react-17 sids may be different each time
TODO: remove, once react-17 support is deprecated
bug is not reproduced, hmm
react-dom of 18 renders empty string slightly different, but it is not a concern of tests for effector-react at all
also IS_REACT_ACT can just be always true, since react-17 does not know about that
refactor react 17 script
Previous custom implementation prevented re-computation of `fn`, if none of the keys in `useStoreMap` was changed

This test catches this behaviour and will pass with previous implementation,
but currently it fails with the new one, based on official `use-sync-external-store`, since `useSyncExternalStoreWithSelector` does not accept keys

Need to add some custom memoization for that in the new implementation
It is needed to comply with previous behavior of useStoreMap
inline condition instead of function, one return instead of few

@zerobias zerobias left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Great work! Big thanks 🙏🏻

@zerobias
zerobias merged commit 7961695 into effector:master May 15, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effector-react effector-react package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

useStoreMap is broken with React 18.

4 participants