Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Kenneth Lum
Kenneth Lum

Posted on • Edited on

     

Having fun with React Custom Hooks

It can be quite fun with Custom Hooks in React.

Let's say we just think of, I want a company that can give me a countdown from 3 to 0, and then give me a way to reset the count.

So we could just write this:

exportdefaultfunctionApp(){const[count,reset]=useXYZCompany();return(<divclassName="App"><h1>{count}</h1><buttononClick={reset}>Reset</button></div>);}
Enter fullscreen modeExit fullscreen mode

That's simple enough. It does not do anything imperative. It follows the line that in React, a lot of things are just declarative... all the way down to when we need to have something imperative to make it work.

So let's say this XYZCompany uses an iPhone to do the job:

functionuseXYZCompany(){const[count,reset]=useIPhone();return[count,reset];}
Enter fullscreen modeExit fullscreen mode

For simplicity, we just make each level return the same count and reset function. We could change it so that the XYZCompany provides some extra functions instead of just a countdown number.

Likewise, the iPhone uses an iPhoneApp:

functionuseIPhone(){const[count,reset]=useIPhoneApp();return[count,reset];}
Enter fullscreen modeExit fullscreen mode

The iPhoneApp does the imperative thing. It uses useEffect to run something:

functionuseIPhoneApp(){const[count,setCount]=useState(3);useEffect(()=>{letintervalID;if(count>0){intervalID=setInterval(()=>{setCount(count-1);},1000);}return()=>intervalID&&clearInterval(intervalID);});functionresetFn(){setCount(3);}return[count,resetFn];}
Enter fullscreen modeExit fullscreen mode

which is to simply decrement the count. Note that this useEffect runs every time, and I notice this is the common style that React code is written: it just "do" and "undo", so that we don't have to worry about anything, such as thecount being the same from the closure. Each time, it just "undo" the previous task, and "do" the new task (of setting up the timer). It is like mathematical induction: if we know this step is correct, then undoing it and redoing it at a different state is also correct, and therefore, everything is correct.

So we can see the code running at:https://codesandbox.io/s/gallant-cloud-177mn?file=/src/App.js

When we press the Reset button, it is to tell the XYZCompany to do a reset. And then XYZCompany uses the iPhone and tells the iPhone to reset. The iPhone in turns tells the iPhoneApp to do a reset.

We don't have to go that many levels down. We can directly useuseIPhoneApp() in the main component, but it is just to show how it would still work after many levels down.

ThesetState() is written so that when it updates any value, any user, all the way to the top, will be re-rendered (re-invoked). So App would call useXYZCompany, and then call useIPhone, and then call useIPhoneApp.

So that's the methodology: we just get back some value from our custom hook. It looks static, but don't worry about it. As long as somewhere down the line, if it has asetState(), then it will "magically" get down to you, appearing to be "changing the static value", as in the case ofcount.

A random text shifter

We can also make a random text shifter, so that it will randomly shift some text. The custom hook is calleduseShifter(). The code:

functionuseShifter(){const[shift,setShift]=useState(0);useEffect(()=>{constintervalID=setInterval(()=>{setShift((shift)=>{if(shift<0)return-shift;elseif(shift>0)return0;elseif(Math.random()<0.1)return-Math.random()/9;});},33);return()=>intervalID&&clearInterval(intervalID);},[]);return{position:"relative",left:`${shift}em`,top:`${shift/3}em`};}exportdefaultfunctionApp(){constshifter=useShifter();return(<divclassName="App"><h1className="message"style={shifter}>Hello</h1></div>);}
Enter fullscreen modeExit fullscreen mode

Demo at:https://codesandbox.io/s/optimistic-hamilton-1u9dv

This is another custom hook for a morpher shifter:https://codesandbox.io/s/epic-forest-kqt1d?file=/src/App.js

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Web Front End developer. Worked at Apple, Intuit, and Facebook before
  • Location
    Silicon Valley
  • Joined

More fromKenneth Lum

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp