Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Hooks] useContext derivation performance issue #87

Closed
dantman opened this issue Nov 15, 2018 · 4 comments
Closed

[Hooks] useContext derivation performance issue #87

dantman opened this issue Nov 15, 2018 · 4 comments

Comments

@dantman
Copy link

dantman commented Nov 15, 2018

A number of libraries currently using HOCs that provide a subset or something derived from context cannot be efficiently ported to hooks because they only use a portion of the context.

When the component they wrap is a PureComponent, as a HOC these libraries only trigger updates when the data they send through props changes. However if they were to use useContext this would result in the component being rendered on every context change, even if the returned data is memoized and no re-render is needed. If the overall context changes frequently, this would mean regular unwanted re-renders.

This includes HOCs like react-redux's connect and Material UI's withStyles.

I think this could be solved by allowing useContext to accept a second argument:

const data = useContext(Context, transformFunction);

The second argument to useContext would be a function that would accept the context value and return another value based on it which would be the return value of useContext (i.e. the default when not specified would essentially be data => data).

React would be able to use this function on context changes. If the context changes but other state/props have not changed React could pre-execute the transformFunction and if the return value has not changed could skip the render. At the very least if the component uses React.memo.

I do recommend treating the transformFunction similar to an effect, i.e. allowing hooks to be used in it. So that it's possible to use useMemo inside the function.

@markerikson
Copy link

markerikson commented Nov 17, 2018

Already being tracked in facebook/react#14110 .

Specifically to your suggestion, note that there's already a second argument: useContext(ContextObject, observedBits).

@mocheng
Copy link

mocheng commented Nov 27, 2018

The traditional Context API has prop unstable_observedBits, while the hook API hide the unstable_ attribute of this secret feature.

@markerikson
Copy link

@mocheng : that's not sufficient for most use cases, no. That would require the context provider to have already calculated the derived values so it can set the bit patterns appropriately, or at least indicate which pieces of the context state have changed (in which case the consumer needs to have also indicated which pieces it's interested in). There's some overlap, but not enough.

@gaearon
Copy link
Member

gaearon commented Aug 24, 2021

Hi, thanks for your suggestion. RFCs should be submitted as pull requests, not issues. I will close this issue but feel free to resubmit in the PR format.

@gaearon gaearon closed this as completed Aug 24, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants