是否应忽略该场景下的react-hooks/exhaustive-deps ESLint规则?
解决方案
针对你的需求,这里提供几种符合React Hooks规范且能满足要求的实现方式:
方案一:使用useRef跟踪最新搜索词(兼容性最优)
通过useRef保存最新的search值,让fetchData仅依赖page,同时能获取到最新的搜索词:
import { useState, useEffect, useCallback, useRef } from 'react'; const YourComponent = () => { const [page, setPage] = useState(1); const [search, setSearch] = useState(""); const [data, setData] = useState([]); // 用ref实时同步最新的search值 const searchRef = useRef(search); useEffect(() => { searchRef.current = search; }, [search]); // fetchData仅依赖page,使用ref.current获取最新search const fetchData = useCallback(() => { get({ page: page, search: searchRef.current }).then(setData); }, [page]); // 仅在page变化时触发数据获取 useEffect(() => { fetchData(); }, [page, fetchData]); return ( <div> <Input value={search} setValue={setSearch} /> <Button onClick={fetchData}>Search</Button> {data.map(v => <div key={v.id}>{v}</div>)} <Select value={page} setValue={setPage} /> </div> ); };
方案二:让fetchData接收参数(明确传递依赖)
将page和search作为参数传入fetchData,避免函数依赖外部state,同时结合useRef解决闭包捕获旧值的问题:
import { useState, useEffect, useCallback, useRef } from 'react'; const YourComponent = () => { const [page, setPage] = useState(1); const [search, setSearch] = useState(""); const [data, setData] = useState([]); const searchRef = useRef(search); useEffect(() => { searchRef.current = search; }, [search]); // fetchData接收参数,无需依赖外部state const fetchData = useCallback((targetPage, targetSearch) => { get({ page: targetPage, search: targetSearch }).then(setData); }, []); // page变化时,传入最新的page和search调用 useEffect(() => { fetchData(page, searchRef.current); }, [page]); return ( <div> <Input value={search} setValue={setSearch} /> <Button onClick={() => fetchData(page, search)}>Search</Button> {data.map(v => <div key={v.id}>{v}</div>)} <Select value={page} setValue={setPage} /> </div> ); };
方案三:使用React 18+ useEvent(代码最简洁)
如果你的项目使用React 18及以上版本,可以开启实验性的useEvent API,它能返回一个稳定的函数引用,同时内部可以访问最新的state:
import { useState, useEffect, useEvent } from 'react'; const YourComponent = () => { const [page, setPage] = useState(1); const [search, setSearch] = useState(""); const [data, setData] = useState([]); // useEvent返回稳定的函数,内部可获取最新state const fetchData = useEvent(() => { get({ page: page, search: search }).then(setData); }); useEffect(() => { fetchData(); }, [page]); return ( <div> <Input value={search} setValue={setSearch} /> <Button onClick={fetchData}>Search</Button> {data.map(v => <div key={v.id}>{v}</div>)} <Select value={page} setValue={setPage} /> </div> ); };
注意事项
- 不要直接通过
// eslint-disable-next-line react-hooks/exhaustive-deps忽略规则,这可能导致闭包陷阱(比如fetchData使用旧的search值)。 - 渲染列表时记得给每个元素添加唯一的
key属性,避免React警告。
内容的提问来源于stack exchange,提问作者junchaw
相关产品推荐
相关产品推荐

