You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native屏幕间传数据触发Too many re-renders无限循环异常求助

解决React Native中Too many re-renders异常及屏幕间数据传递问题

我来帮你彻底排查这个问题——你遇到的无限重渲染完全是因为错误的状态更新时机导致的,咱们一步步拆解问题并给出解决方案:

问题根源分析

你在MainScreen里犯了一个典型的React新手错误:把addProduct(...)直接写在了VirtualizedList的data属性中。这会引发致命的循环:

  • React组件每次渲染时,都会执行data属性里的表达式,也就是调用addProduct函数
  • addProduct内部调用了setProducts,这会触发组件状态更新,进而引发新一轮渲染
  • 新的渲染又会再次调用addProduct,再次触发状态更新... 直到React触发Too many re-renders的保护机制

另外还有个小问题:你用JSON.stringify处理传递的参数完全没必要,直接传递原始数据会更便于后续处理。

解决方案与修正代码

1. 修正MainScreen:用useEffect处理导航参数

我们需要在组件挂载或导航参数变化时,才去添加新产品,而不是每次渲染都执行状态更新。用useEffect监听导航参数变化是标准做法:

import { useEffect, useState } from 'react';
import { VirtualizedList } from 'react-native';

// 导入你的GoalItem组件
import GoalItem from '../components/GoalItem';

function MainScreen(props: any) {
  const [products, setProducts] = useState<any>([]);

  // 监听导航参数,有新数据时更新产品列表
  useEffect(() => {
    const newProduct = props.navigation.getParam('input');
    if (newProduct) {
      // 这里用函数式更新,确保拿到最新的products状态
      setProducts(prevProducts => [
        ...prevProducts,
        { id: Math.random().toString(), value: newProduct }
      ]);
      // 可选:如果需要避免重复添加相同参数,可以清空导航参数
      // props.navigation.setParams({ input: null });
    }
  }, [props.navigation]);

  // 删除产品的处理函数
  const removeGoalHandler = (id: string) => {
    setProducts(prevProducts => prevProducts.filter(item => item.id !== id));
  };

  return (
    <VirtualizedList 
      keyExtractor={(item: any) => item.id} 
      data={products} 
      // VirtualizedList需要指定这两个方法(如果用FlatList会更简洁)
      getItemCount={() => products.length}
      getItem={(data, index) => data[index]}
      renderItem={itemData => (
        <GoalItem 
          id={itemData.item.id} 
          onDelete={removeGoalHandler} 
          title={itemData.item.value} 
        />
      )} 
    />
  );
}

2. 优化AddingScreen:传递原始数据

不需要对传递的参数做JSON序列化,直接传递原始值即可:

function confirmProduct() {
  props.navigation.navigate('Main', { input: enteredProduct });
  setEnteredProduct('');
  setAmount('');
}

额外注意事项

  • 永远不要在JSX的属性中直接调用会修改状态的函数,这是引发无限重渲染的高频场景
  • 如果使用的是React Navigation 5及以上版本,推荐用useRoute钩子获取参数,比getParam更直观:
    import { useRoute } from '@react-navigation/native';
    
    // 在组件内部
    const route = useRoute();
    const newProduct = route.params?.input;
    

内容的提问来源于stack exchange,提问作者Michał Wojdyla

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 05:34:06