In this lesson we'll explore how to combine useEffect
with useState
to create a reusable hook. It will listen add a window listener for mousemove
and update state with each movement.
Instructor: [00:01] Hooks can be combined to create logical pieces of code that are reusable across all of your functional components. Let's open up our useMousePosition file and create a function that will be our hook.
[00:14] To follow appropriate naming convention, we'll start our function with "use." So say "export const useMousePosition." This will be the start.
[00:26] The reason it starts with "use" is because React has released a plugin that will actually lint for any mistakes that you make with hooks that starts with the name "use."
[00:39] Back in our app, we'll import useMousePosition from our function. It will then return a position. We want it to return position, which will be of our mouse. Then useMousePosition will be the function that we call.
[01:04] We need to implement this. We'll need to get access to the two hooks. We'll say, "import useEffect and useState from React."
[01:21] We need to set up our default state. We're going to say "const position," which will hold onto the position of the mouse, as well as the set position, which is just the updater for it.
[01:33] We'll say, "use state" and pass in X of zero and Y, zero. This X and zero will just be the default state for the first time that this particular hook is instantiated.
[01:51] We need to create our effect. We say, "useEffect," which will create a hook for us that will be equivalent of doing something in componentDidMount and/or componentDidUpdate. Because we're attaching a listener to a function that we are creating, we're just going to say, "Empty array here."
[02:12] That says to React that we want you to look inside of here. If anything changes, then reinitialize this hook and clean everything up. However, with an empty array nothing changes, so this hook will only run once until the component is unmounted.
[02:31] We will do a window.addEventListener for mousemove. Then we'll need to call a function. However, we have one particular issue in that when we return our cleanup function...
[02:44] This cleanup function will clean up whatever side effects of these inside of this hook that we've set. In our case, we've added an event listener, so we need to remove our event listener. It needs to reference the same exact mousemove function that we attached here.
[03:02] In order to do that, we'll just create a function within our useEffect. Say, "const set from event." That will be an event.
[03:16] Then we can simply call our set position with the position of the mouse. X is e.client.x and Y, e.client.y.
[03:31] Because this will only run a first time, this just creates the same exact function that references the setter from our useState. We can pass in our set from event here and then the same exact function to our removeListener of set from event.
[03:52] The final thing to do is just return our position -- return position. We have a reusable hook that will be able to automatically setState and return that position inside of a render. We can then render our position.x and position.y. If we view this in the browser, we can see that when we move our mouse, it's automatically updating the X and the Y.