React Native展示后端数据遇问题:array.push无效且useState触发无限循环
React Native中useState无限循环与数组更新无效的修复方案
问题根源分析
- 无限循环触发原因:组件每次渲染时都会直接执行
checkToken()和dispatch(authAction.Favorite(id)),而setId、setInformations会触发组件重新渲染,进而再次执行这些代码,形成闭环循环。 - 数组更新无效原因:
- 组件每次渲染都会重新声明
let array = [],之前的push操作结果会被重置 - 在
map循环内频繁调用setInformations,既低效又会导致状态混乱 id是异步更新的,第一次dispatch时id还是初始空字符串,无法正确请求数据
- 组件每次渲染都会重新声明
- 页面无内容渲染:
informations.map中的JSX没有返回,导致组件无法渲染任何内容
修复后的完整代码
import React, { useState, useEffect, Alert } from "react"; import { View, Text, Image } from "react-native"; import AsyncStorage from "@react-native-async-storage/async-storage"; const jwtDecode = require("jwt-decode"); import { useDispatch } from "react-redux"; import * as authAction from "../redux/actions/authAction"; const FavoriteScreen = (props) => { const [id, setId] = useState(""); const [informations, setInformations] = useState([]); const dispatch = useDispatch(); const checkToken = async () => { const token = await AsyncStorage.getItem("token"); if (!token) { console.log("coucou le token n'existe pas"); Alert.alert("Vous n'êtes pas connecté à un compte existant"); return; } const decoded = jwtDecode(token); setId(decoded._id); }; // 组件挂载时仅执行一次Token验证 useEffect(() => { checkToken(); }, []); // 当id更新后,再发起收藏数据请求 useEffect(() => { if (!id) return; // id为空时不执行请求 dispatch(authAction.Favorite(id)) .then((response) => { // 直接使用接口返回的数组更新状态,无需手动push setInformations(response.array); }) .catch((error) => { console.error(error); }); }, [id, dispatch]); return ( <View> {informations.map((data, index) => ( // 列表渲染必须添加唯一key属性 <Text key={index}>{data.image_url}</Text> ))} </View> ); }; export default FavoriteScreen;
修复细节说明
- 用useEffect管控副作用:
- 第一个
useEffect依赖空数组,仅在组件首次挂载时执行Token验证,避免重复调用 - 第二个
useEffect依赖id和dispatch,仅当用户ID更新后才发起数据请求,确保使用最新的有效ID
- 第一个
- 正确更新数组状态:直接将接口返回的数组赋值给状态,避免临时数组的重置问题,同时减少不必要的状态更新次数
- 修复渲染逻辑:在
map中返回JSX元素,并添加key属性,符合React列表渲染的规范 - 处理异步状态边界:新增
if (!id) return判断,避免向后端传递空ID请求无效数据
内容的提问来源于stack exchange,提问作者Nicolas
相关产品推荐
相关产品推荐

