Original address: blog
preface
React 16.8 was released on February 6, 2019. It brings Hooks that allow us to use state and other React features without having to write classes. The birth of a new technology is bound to affect the original thinking mode, and there will be many unexpected scenes and traps in the initial application, which requires us to clearly know where there may be potential problems and what more perfect writing methods are available before using them. This is also the original intention of writing this article. In July, our team began fully using Hooks techniques on the new project, and during that time we encountered and resolved a number of bugs while gaining a deeper understanding of functional components.
Learn the basics of React Hooks before starting this article. Many of the problems are explained in the official FAQ, and it is also a good habit to read official documents regularly.
This article introduces some Hooks that I have encountered while using Hooks. There may be others that I haven’t found or written down yet, but I hope that reading this article will help you quickly learn the Hooks and tricks that enable you to develop high-quality functional components. Let’s start with useState.
useState
In Class Component, use state to store Component state, use setState to update, and provide the useStateAPI in Hooks to create a state.
The state structure
UseState takes an initialState and returns a state and a function to update the state. InitialState can use either base data types or reference data types such as arrays, objects, and so on. It is recommended to use multiple USestates to define a state according to its correlation degree and function.
In the following example, we set the state data based on the data returned by the back-end interface {data: [Tom, Jerry], total: 2, result: true}. The first method simply stores all the request parameters and return data in a userState, so let’s examine why this is not recommended.
First, the returned data contains the data field Result that does not need to be stored in state. Second, putting data and requestParams in the same state may seem simple and only need to maintain a userState, but if you need to rely on data or requestParams in useEffect, it will be very troublesome. And requestParams will need to be updated each time the data returned from the back end is fetched.
Not recommended
const [userState, setUserState] = useState({
data: [].total: 0.requestParams: { id: 1 },
result: true
})
Copy the code
The recommended way to write it
const [userData, setUserData] = useState({ data: [].total: 0 })
const [userParams, setUserParams] = useState({ id: 1 })
Copy the code
Avoid double counting
If initialState is a function, useState immediately executes the function and gets the return value of the function on initialization, undefined if there is no return value. The important thing to note here is that each component re-render causes the functions in useState to be recalculated, and closure functions can be used here to solve the problem. After optimization, the loop function is executed only once when the component is initialized.
This example can be viewed in the CodeSandbox
Before optimization
const loop = (a)= > {
console.log("calc!");
let res = 0;
for (let i = 0, len = 1000; i < len; i++) {
res += i;
}
return res;
};
const [value, setValue] = useState(loop());
Copy the code
The optimized
const App = (a)= > {
const [value, setValue] = useState((a)= > {
return loop();
});
}
Copy the code
Update the state
In some cases, if you need to calculate the current state from the previous state, you might want to use the following pre-optimization method. However, it is important to note that the count may not be up to date under some closure scenarios, which can lead to calculation errors. The official method is recommended here.
Before optimization
function Counter() {
const [count, setCount] = useState(0);
return <button onClick={()= > setCount(count + 1)}>+</button>
}
Copy the code
The optimized
function Counter() {
const [count, setCount] = useState(0);
return <button onClick={()= > setCount(prevCount => prevCount + 1)}>+</button>
}
Copy the code
The next article introduces tips for using useEffect and useEffect.