Getting started with React Hooks — Part 2

I wrote a post last week which entails some of the Hooks we must have heard about. How about checking out some other hooks?
Before I continue, it’s not a necessity to make use of Hooks. You could use the class-based approach if you’re more comfortable with that. Even Dan Abramov, a top contributor to React still said he would use JavaScript classes in some cases.
Let’s get Started
I briefly wrote about the useReducer in the last post which was more like JavaScript array method(Reduce), and not what we might exactly be expecting.
Don’t sweat it, that’s how redux work anyways! It’s more like the reduce method but can do more than just passing a direct value to it.
The only difference is the way the code was written. No Types, No switch statements to differentiate types and return a new set of state based on the type specified.
How about we write one with types?
Yeah, we’ll be building a simple structure to:
- Add 1 to the state
- Subtract 1 to the state
- Multiply the state by 2
- Add a number from input to the state
- Reset the state
Let’s start by creating our types:
const TYPES = { ADD_ONE: "ADD_ONE", SUBTRACT_ONE: "SUBTRACT_ONE", MULTIPLY_BY_TWO: "MULTIPLY_BY_TWO", RESET: "RESET", ADD_CUSTOM: "ADD_CUSTOM"};
After creating our types, the next thing to do is create our reducer. And we could do that using this piece of code:
const [state, dispatch] = useReducer((state, action) => { switch (action.type) { case TYPES.ADD_ONE: return state + 1; case TYPES.SUBTRACT_ONE: return state - 1; case TYPES.MULTIPLY_BY_TWO: return state * 2; case TYPES.ADD_CUSTOM: return state + action.value; case TYPES.RESET: return 0; default: return state; }}, 0);
We’ll return a new state based on the type and value passed to the dispatch function.
We can then, go ahead to create our onClick handlers:
const addOne = () => dispatch({ type: TYPES.ADD_ONE });const subtractOne = () => dispatch({ type: TYPES.SUBTRACT_ONE });const mulitiplyByTwo = () => dispatch({
type: TYPES.MULTIPLY_BY_TWO
});const reset = () => dispatch({ type: TYPES.RESET });const addCustom = () => dispatch({
type: TYPES.ADD_CUSTOM,
value: num
});
We’ll pass the handlers to our button, and we’re good to go :)
We can check out the implementation here:
UseRef
This keeps a reference to the element assigned to it. No! It doesn’t just do that, and you don’t need an element to use ref. You could just see it this way “A container which is an object that has a current property, which is initialized to the passed argument(initialValue).”
Basic Usage
Creating a ref is as easy as writing this:
//initial value here is null which is our current value
const myRef = useRef(null);
Note that: if no initial value is passed, myRef.current
will be undefined.
Passing ref to input and controlling it
Well, if you’re not new to ref you’d know it could be passed to inputs, and it’s as simple as writing this:
<input type="text" value={state} onChange={handleInputChange} ref={inputRef}/>
and we could make a button place focus on this input whenever the button is clicked using this:
const inputRef = useRef();const handleFocus = () => inputRef.current.focus();<button onClick={handleFocus}>Place Focus on Input with Ref</button>
Using ref to get the previous state
One other thing we’d try to do is getting the previous state using refs. Isn’t that awesome? It really is.
So here’s how we’ll do it:
const prevRef = useRef();useEffect(() => { prevRef.current = state;});const prevState = prevRef.current;
Wow! That’s quite simple, what about creating a custom hook that can be re-used in several other components?
const usePrev = state => { const prevRef = useRef(); useEffect(() => {
prevRef.current = state;
}); return prevRef.current;};
and we could call usePrev by passing our state to it
const prevState = usePrev(state);
We can check out the implementation here:
UseContext
In my opinion, this is one of the hottest react hooks. With this, you can get rid of nesting multiple context consumers, creating Higher Order Components to pass the consumer’s context values to the component, and accessing these values via props.
Sigh. That’s a whole lot of process.
How about we get the value directly by just passing the Context to useContext and we’re good to go.
Let’s see how this plays out, we’ll start by creating a GitHub Context with it’s provider:
const GitHubContext = React.createContext();const GitHubProvider = ({ children }) => {const [repos, updateRepos] =
useReducer((acc, cur) => acc.concat(cur), []);
useEffect(() => { fetch("https://api.github.com/users/ooade/repos")
.then(res => res.json())
.then(data => data.map(
({ id, name, html_url: url }, i) => { setTimeout(() => {
updateRepos({ id, name, url });
}, i * 200); }));},[isEqual(repos)]);return (
<GitHubContext.Provider value={repos}>
{children}
</GitHubContext.Provider>
);
};
Yay! That’s our context provider. It doesn’t do much than just to pass in my boring repositories with some specified intervals for a boring animation I came up with.
So, we said we’re doing away with consumer. Now how do we get the data in the desired component? You guessed right “useContext”.
Here’s how it’s done:
const repos = useContext(GitHubContext);
As simple as that, our data can be used in our component. This context value can be gotten from any child component, no need for a consumer, no need for a Higher Order Component to wrap around the components that needs the value. It just works.
That’s it! The first hooks I discussed and these, are the ones you’d use while working on most projects. If you have any questions, feel free to shoot it at me.
And if you’re looking for a React.js Developer to employ in your awesome company, feel free to hit me up on Twitter.
Thanks for your time, I wouldn’t mind some applause if you find this interesting. I’m fired up!!!!!!!!!! Next article in a bit!