I will start by giving props to the site useHooks.com, which has afforded me the absolute best breakthrough I have yet to receive in my journey into the world of React.
First, what is a hook? In React terms, a hook is a way to mimic the functionality of a class without having to write and instantiate a class. OK, for the non-programmers in the room, what is a class? The best way I can explain it is that a class is a kind of container template. Inside of the class we find methods and properties. Methods are blocks of code we can execute by name. Properties are variables defined inside the class that can be used outside of the class. However, classes can’t be used as-is; they need to be instantiated, which is to say, a copy has to be made of the original and given a new identity. Here’s a quick pseudocode example of a class.
export class MyClass() {
constructor(){
this.myProperty = "";
}
const AddNumbers = (a,b) => {
return a+b;
}
}
In order to work with a class, we instantiate it, meaning we create a working copy that can exist entirely on it’s own, independent of other instances of the same class.
const instanceOne = new MyClass();
const instanceTwo = new MyClass();
instanceOne.myProperty="Blue";
instanceTwo.myProperty="Red";
console.log(instanceOne.AddNumbers(3, 5)); //8
console.log(instanceTwo.AddNumbers(16, 27)); //43
console.log(instanceOne.myProperty); //Blue
console.log(instanceTwo.myProperty); //Red
Basically the point of a class in traditional programming is to create a kind of template full of functionality and data slots that we can create when we need it, and which can operate independently of other instances of the same class. It allows us to craft processing rules once and then just re-use whenever we need the exposed functionality.
In Javascript, we can do classes, but classes are considered to be “OOP” constructs — object oriented programming. A class is technically an object, and Javascript is not an OOP language. In order to officially move beyond this way of thinking, React came up with “hooks”.
React has a lot of built-in hooks that get a lot of use, such as useEffect and useState. The first, useEffect can be deployed when we want to run code in response to a change in other code, and the second, useState, is how React “remembers” information between re-renders. The naming convention for hooks is “use-” followed by what the hook does.
The good news is that hooks aren’t really anything special, meaning we can create our own. The site useHooks.com has several exploded hooks available for copy and use, which is what provided me with a way to handle one of the most painful parts of my ongoing game project: working with Firebase authentication. I won’t lay it all out here, but know that my original code attempts covered several hundred lines, whereas with the hook I am now down to this:
const authUser = useAuth();
In effect, this is being used in the same way as if I had created a class and put all of my code inside the class. Originally I had used a class, and then exposed it using a context (which is a whole other post). This particular hook uses contexts, but is completely internal, meaning that I can call methods defined in the hook which take advantage of context data I have set up at a higher level with only this one line of code…technically. There’s more too it once the “one line of code” has been deployed:
const authUser = useAuth();
const WhoAmI = () =>{
if (authUser.user) {
return ( <Row><Col>Welcome back, {authUser.user.displayName} </Col></Row> )
}else{
return null
}
}
return (
<div>
<WhoAmI />
</div>
}
Because the useAuth hook handles all of the dirty parts of interfacing with Firebase Auth, I don’t have to worry about re-writing the heavy lifting every time I need to know something about the currently logged in user, which amounts to the following:
- Taking the user’s email and password and sending them to the Firebase Auth API
- Receiving a response of the Firebase Auth user object
- Using the Firebase data to look up the user in the project’s data store
- Putting the data store information into a local JSON object
- Storing the JSON object in a state variable
- Retrieving the contents of the state variable when I need information about the user (like the displayName)
The important thing to know is that this isn’t just about displaying the user’s name. Since this is a game project, I need to know the Firebase-issued JWT so I can authenticate the user on each request. By building this into the hook, I can get access to the token whenever I need to access it without having to call to Firebase each time.
This goes beyond just Firebase, as I’ve copied the original format to deal with API calls to the game server (for character lists, creation, deletion, and selection) and the Colyseus events (joinRoom, leaveRoom, rejoinRoom). Deploying the hook paradigm is making coding so much easier, considering I had been trying to find a proper React-slash-Javascript way to work the class design since I started this project. Were this a C# project, I would have completely relied on interfaces, classes, and factories to encapsulate and abstract functionality, but with React, hooks have provided me with the same kind of functionality.
1 Comment
ReactJS - Custom Hooks for Searching » Scopique's
July 29, 2021 - 10:22 AM[…] React and Colyseus – Custom React Hooks […]