react-copy-write icon indicating copy to clipboard operation
react-copy-write copied to clipboard

Add `useCopyWrite` and `useCopyWriteMemo`

Open davej opened this issue 5 years ago • 2 comments

useCopyWrite Hook

Hooks are a new addition in React 16.8. They let you use react-copy-write without using render functions.

Let's write our Avatar component in the previous example using the useCopyWrite hook instead.

const Avatar = () => {
  const [src, avatarTheme] = useCopyWrite([
    state => state.user.avatar.src,
    state => state.theme.avatar
  ]);
  return <img src={src} style={avatarTheme} />;
};

Preventing unnecessary updates with useCopyWrite

There is one notable difference between using the render prop approach (<Consumer />) and using the hook approach (useCopyWrite). Using the render prop will only re-render if selected state changes, however, this is currently not possible with the useCopyWrite hook. You can visit this issue for more information.

There is a workaround however, you can use the useCopyWriteMemo hook. This will use the useMemo hook internally to check for state changes.

const Avatar = () =>
  useCopyWriteMemo(
    [state => state.user.avatar.src, state => state.theme.avatar],
    ([src, avatarTheme]) => <img src={src} style={avatarTheme} />
  );

davej avatar Feb 12 '19 15:02 davej

Just used this in a real-world project and it doesn't work if the mutate function is outside of the component because it violates the "Hooks can only be called inside the body of a function component" rule. Docs here.

I'll leave this open just in case anybody has ideas for a fix to this issue but feel free to close.

davej avatar Feb 15 '19 17:02 davej

Surely something like this would be better?

  const [localState, setState] = useState()
  useCopyWriteMemo(
   [state => state.user.avatar.src, state => state.theme.avatar],
   setState
  );

  return <div>{JSON.stringify(state)}</div>

janbaykara avatar Apr 23 '19 12:04 janbaykara