Skip to main content

React Hooks

· 4 min read
VisualDust
Ordinary Magician | Half stack developer

Hooks are a new addition in React 16.8. They let you "hook into" React state and lifecycle features from function components. Hooks don't work inside classes — they let you use React without classes. In older React, it's hard to reuse stateful logic between components. The older React doesn't offer a way to "attach" reusable behavior to a component. With Hooks, you can extract stateful logic from a component so it can be tested independently and reused. Hooks allow you to reuse stateful logic without changing your component hierarchy. This makes it easy to share Hooks among many components or with the community.

There are nine of them:

HookMotivation
useState
warning

There are some important things to konw about React Hooks before using them

  • You can only use React Hooks in function components, in a React.Component ypu cannot use Hooks here because classes already have their own way to do the same things as React Hooks.
  • Every time your function runs, React Hooks must be called in the exact same order. You must put your hooks at the top level of your function. You cannot call hooks conditionally (e.g. put it into an if statement, for loop etc.), or you get errors.

After you get familiar with the built-in Hooks, you can also build your own Hooks.

The useState Hook

The useState is a Hook that allow you to update and rerender components in a pure logical way:

import React, { useState } from 'react';

function Example() {
// Declare a new state variable, which we'll call "count"
const [count, setCount] = useState(0);

return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}

The code above forms a counter. To say how, we call it inside a function scope to add some local state to it. React will preserve the state between re-renders.

DeclarationRequired argsReturens
const [what, setWhat] = useState(/*initial state*/);type:any The initial stateA pair: the current state value and a function that lets you update it.

In the example above, the initial state is 0 because the counter starts from zero.

note

Note that unlike this.state, the state here doesn't have to be an object — although it can be if you want. The initial state argument is only used during the first render.

You can use the State Hook more than once in a single component:

function ExampleWithManyStates() {
// Declare multiple state variables!
const [age, setAge] = useState(42);
const [fruit, setFruit] = useState('banana');
const [todos, setTodos] = useState([{ text: 'Learn Hooks' }]);
// ...
}
warning

**There can be an incorrect way to update: **

function what(){
const [which, abaaba] = useState(100)
function a(){
abaaba(which - 1);
abaaba(which - 1);
}

return{
<>
<button onClick=abaaba>
</button>
<span>
which
</span>
</>
}
}

The rerender procedure would be proceed after the whole click function ended. after click on the button the value of which will only decrease by 1.

Javascript enroles a single thread event loop. There is no way to rerender UI during the click event to be handle. Your first click in the function a looks like:

function a(){
abaaba(100 - 1);
abaaba(100 - 1);
}
// Update or rerender UI

As you can see, the useState hook update the data after each rerendering, but the rerender procedure takes place right after the function ended. The processing order CANNOT be:

function a(){
abaaba(100 - 1);
// Update or rerender UI
abaaba(100 - 1);
}

Stuff like this, you'd better call your hooks at onece which could solve all the problems.

useEffect Hook

The Effect Hook lets you perform side effects in function components

import React, { useState, useEffect } from 'react';

function Example() {
const [count, setCount] = useState(0);

// Similar to componentDidMount and componentDidUpdate:
useEffect(() => {
// Update the document title using the browser API
document.title = `You clicked ${count} times`;
});

return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
note

如果你熟悉 React class 的生命周期函数,你可以把 useEffect Hook 看做 componentDidMount,componentDidUpdate 和 componentWillUnmount 这三个函数的组合。