Building React Hooks: API Considerations and Best Practices
This lesson preview is part of the The newline Guide to Creating a React Hooks Library course and can be unlocked immediately with a \newline Pro subscription or a single-time purchase. Already have access to this course? Log in here.
Get unlimited access to The newline Guide to Creating a React Hooks Library, plus 70+ \newline books, guides and courses with the \newline Pro subscription.

[00:00 - 01:33] If you're familiar user of ReactHanger, you may notice that some of its hooks are having two different APIs. One is returning array and another is object. What is a big deal, you may ask? One of the good rules when you're developing certain custom hooks APIs, mostly those that are holding and exposing some state, is to keep them as close to original React Hooks API as possible. So let's take a simple example using useState. So what do we have here? We have a component of open-close sign that renders open or close depending on its open state, whether it's true or false. All clear, but there is a little of boilerplate needed in order to keep reference to quality of toggle open callback between renders. So our children components are not rendering for no reason because if you change the reference for the React, it will just compare two references. And even though toggle open is exactly the same as it used to be, it will still re-render the button or any other component that will be here. We definitely want to avoid that. That's why we have this useCallBack hook that is coming from the React. That will make sure that this toggle open will never going to be changed between renders because there is no dependencies because here you can pass the dependencies of this particular callback, as you can see it's saying, you know, "steps."
[01:34 - 02:18] But since there's no, we are absolutely safe and this reference will be the same all the time. So the components that will get this callback will never trigger the render because of this callback. So pretty complicated, I know, but I mean, I hope you'll get to understand this one. All right. One important part of every single snippet you see on my screen is that this initial state callback, Boolean, value, etc. It's not a code. It's not a code so you should ignore this gray thing is because it's basically a suggestion. Hence that IntelliJ or WebStorm is showing. So I can just disable that, but I prefer to have it. So just keep it in mind that you don't need to type it and that it's not a piece of a code here.
[02:19 - 02:40] Right. So this one, this snippet can be improved using custom use Boolean hook from ReactHanger. And we're going to implement this one in the next lesson. So check this out. So as you can see, it's way, way, way shorter. As you can see, there's way less code to type.
[02:41 - 03:24] And use Boolean is already kind of keeps it all nice and clean and without any additional boiler plates. So you saving the boiler plate nice, right? And it's pretty same as you state. So you have is open thing, you have is open actions and these actions have a toggle function that basically toggles is open state from to default from false to true. So everything is working nicely and beautifully. So yeah, it's pretty obvious API feels like it's a part of react itself, even though it's not. So state on the left, everything that is changing state is on the right, all the callback setters, methods, etc. It's intuitive.
[03:25 - 05:22] And let's check out another example, I'll have it here on the right. So same component. And let me change the scratch. But another API, it's an original API of reactHanger from the version one in the version two, there is already also array one that we've used before. And this one is, you know, not that's right forward, because it returns object here. And we have to just structure this object into the open and toggle open. And we need to rename value and toggle so they are not unnamed. We can definitely remove this one. Yeah, but we want to rename it because it makes sense. And same for the toggle open, we want to do the same thing. So still pretty straightforward, right? You can read the docs and you will immediately understand the API. But array one is more, you know, react looking and as you can see, this one is pretty clear. And this one is not that clear, to be honest. So let 's take a look at last scratch. These are two APIs, right? And what's the worst about the object API is that it looks like they're pretty much identical, right? But they are not in the first snippet in the first snippet at the top, you can pass all the actions as a whole and separately without unnecessary renders because they are memoized under the hood. And the same reference returned all the time. So if you will pass this whole show header or show foot er actions to the other component, everything will be all right, because all this thing is minimized, right? And they never change the reference. And in the second one, we're taking taking the value out of the return object and spreading the rest of the object properties that represent the actions into show header actions. So as you can see, we have a value on the left, everything is all right is a Boolean type. So we will not cause any rerender.
[05:23 - 06:12] But these are same thing as here, show header actions or show footer actions. But the problem here is that when you do the destructuring here, you actually create a new reference every single render, which causes unnecessary render. And it's not really cool. And it's not that obvious for the user, to be honest, not everyone knows internals of JavaScript that well to understand this small issue. Of course, you can then in a restructure yourself and then you can do what we did before. So it'll be toggle, etc. But it's a lot of a lot of typing. And we definitely don't want to do that. So the main conclusion here is that area API is better because it feels closer to react use state, hence it's better to understand.
[06:13 - 06:25] It always returns the same reference for all actions avoiding a needed renders of its children. It's just slightly shorter than object version of API. So with that in mind, let's implement use Boolean ourselves.