React添加空依赖数组仍触发无限渲染循环问题排查
无限渲染问题成因
- 核心问题出在第一个下拉框的
map遍历逻辑中,你直接在组件渲染过程调用了setPc(hit._id)更新状态。
React的执行规则是只要state发生变更,就会触发组件重新渲染,你的代码形成了死循环链路:
组件渲染 → 执行map遍历调用
setPc更新pc状态 → 状态更新触发重渲染 → 再次执行map调用setPc→ 无限循环
你给useEffect加空依赖避免重复请求的操作是完全正确的,问题和useEffect无关,完全是渲染过程中直接修改state导致的。
修复方案
你要实现选择邮编联动第二个下拉的需求,应该给第一个select绑定onChange事件,在用户主动选择的时候更新pc状态,不要在渲染过程中直接赋值。如果需要默认选中第一个邮编,可以在接口请求成功的回调里赋值,修正后的代码如下:
import { useState, useEffect } from 'react'; import axios from 'axios'; import Card from 'react-bootstrap/Card'; function MainCard(){ const [data, setData] = useState({took: {}, timed_out: false, _shards: [], hits: {total: {}, max_score: {}, hits: []}}); const [pc, setPc] = useState(""); useEffect(() => { axios.get("http://localhost:9200/first_name/_search") .then(response => { setData(response.data) // 可选:默认选中第一个邮编 if(response.data.hits.hits.length > 0) { setPc(response.data.hits.hits[0]._id) } }); }, []); return ( <div> <Card className="customCard"> <Card.Body> <select name="postcode" id="postcode" value={pc} onChange={(e) => setPc(e.target.value)} > {data.hits.hits.map(hit => <option value={hit._id} key={hit._id}>{hit._id}</option>)} </select> <select name="type-of-service" id="type-of-service"> {data.hits.hits.filter(hit => hit._id===pc) .map(hit => <option value={hit._source} key={hit._source}>{hit._source}</option> )} </select> </Card.Body> </Card> </div> ) } export default MainCard;
额外注意点
- 所有state更新操作都不能直接写在渲染逻辑里,只能在事件回调、useEffect回调这类非渲染阶段执行
- 渲染列表时记得加唯一
key属性,避免React抛出告警
内容的提问来源于stack exchange,提问作者Hari Rao
相关产品推荐
相关产品推荐

