React 16.8 Hooks - Part 1

The release of React 16.8 gave us a few extra tools to help optimize render speed and easily maintain state. Specifically, hooks provide a way for React to decide when the DOM needs to be updated.
You might say, "Dude, we have that already." And I would say, "correct, but not like this."
Example task:
- Create an input UI where we capitalize every word the user inputs.
Let's take a look at a very simple, statefulReact pre 16.8 component.
classExample{constructor(props){super(props);// boilerplate...// initialize the state countthis.state={text: ""};// bind the change methodthis.handleChange=this.handleChange.bind(this);}handleChange(event){consttext=event.target.value.split(" ").map(capitalize).join(" ");setState({ text });}render(){return<><inputonChange={this.handleChange}/>{this.state.text}</>}}Now, let's take a look at the same component in React 16.8:
First lets make a file called useCapitalizedWords.js and put it in a folder called hooks
// hooks/useCapitalizedWords.jsimport{useEffect,useState}from"react";import{capitalize}from"helpers";exportdefaultfunctionuseCapitalizedWords(){// stateful textconst[text,setText]=useState("");// When text changesuseEffect(()=>{// Update the stored text with capitalized wordssetText(text.split(" ").map(capitalize).join(" "));},[text,setText]);return[text,setText,text.split(" ")];}Now all we have to do is use our hook.
// Example.jsimportuseCapitalizedWordsfrom"hooks/useCapitalizedWords";functionExample(){// [ "", (function setter), [] ]const[text,setText,words]=useCapitalizedWords();return(<><inputonChange={event=>setText(event.target.value)}/>{words.map(word=><divkey={word}>{word}</div>)}</>);}I don't know about you, but I would rather maintain that last example. A simple stateful component should look as simple as it is. That was too easy. Lets try something a bit more difficult.
Example task 2 - async hook
Let's make a UI component that grabs my github avatar. We start with a fresh hook useGithubAvatar.
// hooks/useGithubAvatar.jsfunctionuseGithubAvatar(username="taystack"){// Store the urlconst[url,setUrl]=useState("");// Good UI always knows when a resource is loadingconst[loading,setLoading]=useState(false);// When username changes...useEffect(()=>{// Have an async method in scope of the effectasyncfunctiongetUser(username){setLoading(true);// Update loading boolean// Get the userconstuserResponse=awaitfetch(`https://api.github.com/users/${username}`);/* You can change the next lines to: const user = awaitUserResponse.json(); <- just capture the entire user setUser(user); <- change [url, setUrl] = useState("") to [user, setUser] = useState({}); I would also recommend changing the name of the hook to "useGithubUser" */const{ avatar_url }=awaituserResponse.json();setUrl(avatar_url);// Update returned URL stringsetLoading(false);// Update loading boolean }getUser(username);},[username,setUrl,setLoading]);// bind our dependenciesreturn[loading,url];// return the items we need from this hook}Now when I want to get an avatar url for a user, I just invoke my custom hook! This component below will begin to appear after 100ms and gradually transition opacity over the next 100ms.
constGithubAvatar=({ username, ...props})=>{const[loading,src]=useGithubAvatar(username);return(<img{...props}src={src}style={{opacity: loading ? 0 : 1,transition: "opacity 100ms 100ms", ...props.style}}/>);}GithubAvatar.defaultProps={username: "taystack"};I'm leaving it here for React 16.8 Hooks Part 1
If you have any questions or complaints about the code I wrote, please leave a comment below.
I hope to inspire you into writing your own hooks. Hooks contribute to functional-style programming, which is a good thing. Like the example above shows, <GithubAvatar /> has one job - show the avatar. Even without props.username it knows what to do, explicitly. Same goes for useGithubAvatar. You can expect that hook to return an array of [bool, string]. I will create an exercise on try {} catch() {} for this hook in a later post.
Functional programming techniques like hooks allow developers to separate concerns of the view (rendered material), and the logic of how to get there. When modularized concerns are clearly defined, functional logic becomes much easier to maintain, debug, and contribute to.
React 16.8 Hooks - Part 1
The release of
React 16.8gave us a few extra tools to help optimize render speed and easily maintain state. Specifically, hooks provide a way forReactto decide when the DOM needs to be updated.You might say, "Dude, we have that already." And I would say, "correct, but not like this."
Example task:
Let's take a look at a very simple, stateful
React pre 16.8component.Now, let's take a look at the same component in
React 16.8:First lets make a file called
useCapitalizedWords.jsand put it in a folder calledhooksNow all we have to do is use our hook.
I don't know about you, but I would rather maintain that last example. A simple stateful component should look as simple as it is. That was too easy. Lets try something a bit more difficult.
Example task 2 -
asynchookLet's make a UI component that grabs my github avatar. We start with a fresh hook
useGithubAvatar.Now when I want to get an avatar url for a user, I just invoke my custom hook! This component below will begin to appear after
100msand gradually transition opacity over the next100ms.I'm leaving it here for React 16.8 Hooks Part 1
I hope to inspire you into writing your own hooks. Hooks contribute to functional-style programming, which is a good thing. Like the example above shows,
<GithubAvatar />has one job - show the avatar. Even withoutprops.usernameit knows what to do, explicitly. Same goes foruseGithubAvatar. You can expect that hook to return an array of[bool, string]. I will create an exercise ontry {} catch() {}for this hook in a later post.Functional programming techniques like hooks allow developers to separate concerns of the view (rendered material), and the logic of how to get there. When modularized concerns are clearly defined, functional logic becomes much easier to maintain, debug, and contribute to.