Instantly share code, notes, and snippets.

Embed
What would you like to do?
Examples from "Making Sense of React Hooks"
function MyResponsiveComponent() {
const width = useWindowWidth(); // Our custom Hook
return (
<p>Window width is {width}</p>
);
}
function useWindowWidth() {
const [width, setWidth] = useState(window.innerWidth);
useEffect(() => {
const handleResize = () => setWidth(window.innerWidth);
window.addEventListener('resize', handleResize);
return () => {
window.removeEventListener('resize', handleResize);
};
});
return width;
}
@harkinj

This comment has been minimized.

harkinj commented Nov 1, 2018

Thanks for this. This helped me twig that setting state in a hook causes a re-render of its using/parent component. I read a lot about hooks but missed that point somehow :(

@harkinj

This comment has been minimized.

harkinj commented Nov 1, 2018

It almost feels like using a custom hook is like a #include (I'm showing my age now :)) into the calling function.

@guilherme6191

This comment has been minimized.

guilherme6191 commented Nov 2, 2018

Fun fact; this works on codesandbox:

function useWindowWidth() {
  const [width, setWidth] = useState(window.innerWidth);
  // const handleResize = () => setWidth(window.innerWidth);
  // window.addEventListener("resize", handleResize);
  useEffect(() => {
    setWidth(window.innerWidth);
    return () => {
      // window.removeEventListener("resize", handleResize);
    };
  });

  return width;
}

I'm guessing that is because of the window.innerWidth reference.
https://codesandbox.io/s/rm3v532lwm

@dbismut

This comment has been minimized.

dbismut commented Nov 5, 2018

Hi @gaearon, I'm very new to hooks, but isn't this typically the case where you would opt out from cleaning at each render in useEffect and rather have:

useEffect(() => {
    const handleResize = () => setWidth(window.innerWidth);
    window.addEventListener('resize', handleResize);
    return () => {
      window.removeEventListener('resize', handleResize);
    };
  }, []); // <-- empty array

As suggested in the note from the docs, the empty array makes it so that the effect is run and cleaned up when the component mounts / unmounts.

Otherwise you would add and remove a window listener at each render, right?

@Memfisrain

This comment has been minimized.

Memfisrain commented Nov 7, 2018

Hi @gaearon, I'm very new to hooks, but isn't this typically the case where you would opt out from cleaning at each render in useEffect and rather have:

useEffect(() => {
    const handleResize = () => setWidth(window.innerWidth);
    window.addEventListener('resize', handleResize);
    return () => {
      window.removeEventListener('resize', handleResize);
    };
  }, []); // <-- empty array

As suggested in the note from the docs, the empty array makes it so that the effect is run and cleaned up when the component mounts / unmounts.

Otherwise you would add and remove a window listener at each render, right?

Correct, you can avoid running effect after every render passing empty array for this case. However react team refer to the more complex situation when people introduce memory leaks or break application logic as they forget to run "effect" after component's props are updated.

@bakytn

This comment has been minimized.

bakytn commented Nov 7, 2018

This cool example just demonstrated everything I wanted to know about Hooks. Thank you!!!!

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