Kent C. Dodds: 0:00 The logic that we have here for storing some state into localStorage and keeping it synchronized could be useful in other areas of our application.
0:30 We need to generalize the code that's in our function. Instead of a name, it might make more sense to call this state and setState. Instead of getting the item with the string name, it might make more sense for the user of this function to provide us a key for localStorage, so we'll accept a parameter called key.
0:51 Instead of this as a default value, it might make sense for people to provide us their own default value. We'll accept that as another parameter. We can default that to an empty string just in case they don't want to provide it.
1:05 Then we'll replace that with the default value. We'll replace the string name with a parameter that we accept called key. Then let's make sure we update these two references to that old state value as well.
1:19 Then when we call useLocalStorageState, we're going to need to get access to that stateUpdater function and to the state value itself. Let's return state and setState. We can make our custom Hook have a similar API to useState so it's familiar to people who are used to the useState Hook.
1:39 Then we can come down here. We can get our name and our setName from useLocalStorageState. We'll specify our key as name. Then we're done. That's a pretty straight-up refactor from the code that we had before into a custom function. If we type in here Chuck and then refresh, we'll see that Chuck is still in there.
2:02 One thing I want to call out here is that we prefaced our function with the word use. That's a convention and not required. We could change this to whateverWeWant. Save that. Things will work just as well. We can hit refresh. There we have it.
2:19 The reason that we follow this convention is because the eslint-plugin-react-hooks is able to enforce some of the same recommendations and rules on our custom Hooks as it is on the built-in Hooks because it acts under the assumption that functions that begin with use are custom Hooks.
2:59 We also learned the importance of using the use prefix on our custom Hooks so that we follow the community convention and the ESLint plugin can help us avoid mistakes.
3:09 Incidentally, one such mistake is happening right now. In this index.html file, I can't have ESLint running to show me the mistakes that I'm making. I made a mistake right here in this dependency array. I wonder if you can figure out what it is. I'm missing one of the dependencies for my callback.
3:28 Before, we had this key hardcoded as name. It couldn't ever change. My dependency array didn't need to include that. Now, I'm accepting a key as a parameter from the users of the LocalStorageState custom Hook. They could potentially change that value. If they do, then I need to make sure to respond to that change so that I update local storage and not lose any of the user's work.
3:53 It's important that in your applications you use and follow that ESLint rule so you can avoid bugs like this. With this in mind, we could make this useLocalStorageState Hook a lot more robust by removing the item at the old key if that key has changed. I'm going to leave that as a fun exercise for you to do later.