Open jtwang7 opened 3 years ago
参考文章: How to fetch data with React Hooks?
使用 React Hooks 处理数据请求,思想上同 React Class 组件类似,请求数据并将其存储在 state 中,通过 setState 触发重渲染以更新页面。有以下几点区别:
useEffect(()=>{...}, [])
代替 componentDidMount,注意 useEffect 的第二个参数需要为 []
,避免 setState 写在 useEffect 中导致死循环。
若不为
[]
,useEffect 会在首次创建和重新渲染时触发,内部 setState 出发重新渲染后又会触发下一次 useEffect,导致死循环。
import React, { useState, useEffect } from 'react';
import axios from 'axios';
function App() { const [data, setData] = useState({ hits: [] });
// WRONG useEffect(async () => { const result = await axios( 'https://hn.algolia.com/api/v1/search?query=redux', ); setData(result.data); // 此处会隐式返回一个 Promise 对象,但 useEffect 内第一参数只能返回 null 或一个用于清除的回调函数。 }, []);
// RIGHT useEffect(() => { // 避免直接将 useEffect 第一参数声明为 async 函数 const fetchData = async () => { const result = await axios( 'https://hn.algolia.com/api/v1/search?query=redux', ); setData(result.data); }; // 执行 fetchData(); // useEffect 第二参数为 [],避免死循环 }, []);
return ( ... ); }
export default App;
## 自定义 Hook
同”高阶组件“一样,在函数组件中,可以通过将数据请求逻辑提升到自定义 Hook 中,实现逻辑的复用。
```js
// 将逻辑提取为一个函数,同时返回外界需要的结果(对外暴露操作接口)。
const useDataApi = (initialUrl, initialData) => {
const [url, setUrl] = useState(initialUrl);
// 用 useReducer 整合多个 useState。
const [state, dispatch] = useReducer(dataFetchReducer, {
isLoading: false,
isError: false,
data: initialData,
});
useEffect(() => {
const fetchData = async () => {
dispatch({ type: 'FETCH_INIT' });
try {
const result = await axios(url);
// 获取数据后,通过 payload 传入 reducer,并调用相应的 action 修改数据。
dispatch({ type: 'FETCH_SUCCESS', payload: result.data });
} catch (error) {
dispatch({ type: 'FETCH_FAILURE' });
}
};
fetchData();
}, [url]);
...
return [state, setUrl];
};
// reducer 设计:通过 payload 接收请求的数据结果,更新到 state 中。
const dataFetchReducer = (state, action) => {
switch (action.type) {
case 'FETCH_INIT':
return {
...state,
isLoading: true,
isError: false
};
case 'FETCH_SUCCESS':
return {
...state,
isLoading: false,
isError: false,
data: action.payload,
};
case 'FETCH_FAILURE':
return {
...state,
isLoading: false,
isError: true,
};
default:
throw new Error();
}
};
How to fetch data in React
参考文章: How to fetch data in React
Where to fetch data in React's component tree?
请求数据的位置 = 所有用到该数据的组件的公共父组件内
How to fetch data in React
componentDidMount
内。axios with promise
axios with async/await
How to fetch data in HIGHER-ORDER COMPONENTS?
我们可以将数据请求逻辑提升到高阶组件中,以实现逻辑复用。
高阶组件本质是在接收的组件基础上,增加了一些额外的功能。