Skip to content

Instantly share code, notes, and snippets.

@levity
Last active June 26, 2019 00:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save levity/3ab3e0f88fd28d55fde5444b9d482f98 to your computer and use it in GitHub Desktop.
Save levity/3ab3e0f88fd28d55fde5444b9d482f98 to your computer and use it in GitHub Desktop.
// FAIL
// the fatal limitation of this approach is that we cannot call
// more hooks from inside the `render` method, because that would be
// calling hooks from inside hooks, a no-no.
//
// this component wrapper is for getting props from the store
// and ensuring re-renders take place only when the props you're
// actually using change.
//
// it is based on "Option 3" from this comment:
// https://github.com/facebook/react/issues/15156#issuecomment-474590693
import { useMemo } from 'react';
import useStore from './useStore';
import values from 'lodash/values';
export default function usingStoreProps(selector, render) {
return function(props) {
const [store, dispatch] = useStore();
// the selector must return an object suitable for passing to a component,
// analogous to mapStateToProps from react-redux
const selection = selector(store);
return useMemo(
() => render({ ...props, ...selection, dispatch }),
// eslint-disable-next-line react-hooks/exhaustive-deps
[props, ...values(selection)]
);
};
}
@levity
Copy link
Author

levity commented May 25, 2019

Note to self: could it work to use React.memo instead of useMemo here, removing the constraint on what can happen inside render?

@levity
Copy link
Author

levity commented Jun 26, 2019

or we could call other hooks from within selector

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