React Native中useEffect与map函数重复执行问题求助
问题描述
我有一个从MongoDB获取数据的React Native组件Num,代码如下:
const Num = () => { console.log("how many times do you see this message?") const [data, setData] = useState([]) const [loading,setloading] = useState(true) const url = "http://localhost:3100/cuentas" useEffect(()=>{ fetch(url) .then((response)=>response.json()) .then((json)=>setData(json)) .catch((error)=>console.error(error)) .finally(()=>setloading(false)) },[]) return( <View style={styles.sectionContainer}> {loading ? ( <Text>Loading....</Text>) : ( data.map((post,xid)=>( <TouchableOpacity key={xid} style={styles.button}> <Text style={styles.text}>#{post._id.slice(-2)}</Text> </TouchableOpacity> )) )} </View> ) }
将该组件放入Notas组件的ScrollView中实现滚动展示:
const Notas = () => { return( <ScrollView Style={styles.container}> <View style={styles.sectionContainer}> <Num></Num> </View> </ScrollView> ) }
遇到的问题:Num组件开头的console.log输出3次,对应map函数重复执行。调试发现移除then链后不再重复,尝试把整个函数放进useEffect时,报错“useEffect must not return anything besides a function”,求解决建议。
解决建议
- 开发模式下的正常现象:这是React严格模式(Strict Mode)导致的,开发环境中React会自动执行两次额外渲染(加上初始渲染共3次),用来检测组件的潜在问题,比如不安全的生命周期、重复的副作用等。生产环境打包后,这种重复渲染会自动消失,无需额外处理。
- useEffect错误用法修正:你尝试将整个函数放入useEffect报错,是因为useEffect的回调函数若有返回值,必须是一个清理函数(用于卸载组件时清除副作用)。当前的useEffect写法是正确的,fetch逻辑放在里面没问题,不需要调整结构。
- 可选:减少不必要的状态更新:如果想避免因数据重复导致的重渲染,可以在setData前添加判断,仅当新数据与现有数据不同时更新状态:
.then((json) => { // 用lodash的_.isEqual做深比较,或自行实现复杂数据的比较逻辑 if (!_.isEqual(data, json)) { setData(json); } }) - 修正拼写错误:
Notas组件中的ScrollView属性Style是大写的,应该改成小写的style,虽然这不是重渲染的原因,但会导致样式不生效,建议修正。
内容的提问来源于stack exchange,提问作者Daniel Sanchez Islas
相关产品推荐
相关产品推荐

