React中如何仅在组件挂载和点击Fetch Next User按钮时调用API
问题根源
你的代码出现无限重复API调用是因为触发了状态更新的循环:
fetchUsers依赖users和nextPageNumber两个状态,每次请求成功后这两个状态都会更新,导致useCallback生成新的fetchUsers实例useEffect依赖fetchUsers,实例变更后会重新执行fetchUsers触发新一轮请求,无限循环
修复方案
我们可以通过给fetchUsers新增入参、改用状态的函数式更新来消除不必要的依赖,完全符合ESLint规则且不会出现警告:
import React, {useState, useEffect, useCallback} from 'react'; import axios from 'axios'; const Users = () => { const [users, setUsers] = useState([]); const [nextPageNumber, setNextPageNumber] = useState(1); const fetchUsers = useCallback(async (page) => { try { const response = await axios.get(`https://randomuser.me/api?page=${page}`); // 函数式更新无需依赖外部的users状态 setUsers(prevUsers => [...prevUsers, ...response.data.results]); setNextPageNumber(response.data.info.page + 1); } catch (error) { console.log(error); } }, []); // fetchUsers实例永远不变,仅首次挂载触发一次 useEffect(() => { fetchUsers(1); }, [fetchUsers]); const fetchNextUser = () => { // 点击时传入当前最新的页码即可 fetchUsers(nextPageNumber); } if(users.length === 0){ return <div>No Users available</div> } return( <div> <button onClick={fetchNextUser}>Fetch Next user</button> {/* 补充:randomuser.me返回的id可能为空,用index兜底避免key重复报错 */} {users.map((user, index) => ( <div key={user.id?.value || index}> <div>Name: {user.name.title} {user.name.first} {user.name.last}</div> <div> <img src={user.picture.large} alt="用户头像"/> </div> </div> ))} </div> ) } export default Users;
核心修改说明
- 给
fetchUsers新增page入参,不再依赖外部的nextPageNumber变量,彻底消除该依赖项 setUsers改用函数式更新,直接读取上一轮的users状态,不再依赖外部的users变量useCallback依赖为空数组,实例永远不会变化,因此useEffect仅会在组件首次挂载时执行一次- 点击按钮时直接传入当前最新的
nextPageNumber即可正常请求下一页数据
内容的提问来源于stack exchange,提问作者Narender Saharan
相关产品推荐
相关产品推荐

