Hooks 是 React 16.8 的新增特性,可以让你在不编写类、不使用 state 的情况下使用 Class 的状态管理、生命周期等功能。
Hook 使用规则
Hook 就是 JavaScript 函数,但是使用它们会有两个额外的规则:
- 只能在 React 的函数组件中调用 Hook。
- 不要在循环、条件判断或者子函数中调用。
- 不要在其他 JavaScript 函数中调用。
- Hook 不能在 class 组件中使用
Hooks 官网文档
在 Hooks 获取数据
相当于 componentDidMount 获取数据一次,传空数组
...
function App() {
const [data, setData] = useState({ hits: [] });
const [query, setQuery] = useState('redux');
useEffect(() => {
const fetchData = async () => {
const result = await axios(
`http://hn.algolia.com/api/v1/search?query=${query}`,
);
setData(result.data);
};
fetchData();
}, []);
return (
...
);
}
export default App;
自定义Hook
useDataApi
import React, { Fragment, useState, useEffect } from 'react';
import axios from 'axios';
const useDataApi = (initialUrl, initialData) => {
const [data, setData] = useState(initialData);
const [url, setUrl] = useState(initialUrl);
const [isLoading, setIsLoading] = useState(false);
const [isError, setIsError] = useState(false);
useEffect(() => {
const fetchData = async () => {
setIsError(false);
setIsLoading(true);
try {
const result = await axios(url);
setData(result.data);
} catch (error) {
setIsError(true);
}
setIsLoading(false);
};
fetchData();
}, [url]);
return [{ data, isLoading, isError }, setUrl];
};
function App() {
const [query, setQuery] = useState('redux');
const [{ data, isLoading, isError }, doFetch] = useDataApi(
'https://hn.algolia.com/api/v1/search?query=redux',
{ hits: [] },
);
return null
}
export default App;
FAQ
我应该使用 Hook,class,还是两者混用?
- 不推荐用 Hook 重写你已有的 class,除非打算重写它们。
- 可以混合使用 class 组件和使用了 Hook 的函数组件。
- Hook 应该成为编写 React 组件的主要方式,毕竟是趋势。
避免不必要的重新渲染
- useCallback
- useMemo
- React.memo(
)
https://jancat.github.io/post/2019/translation-usememo-and-usecallback/
参考
[译] 如何使用 React hooks 获取 api 接口数据
https://stackblitz.com/edit/react-xnrgaz