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

React Native报Too many re-renders错误怎么解决?跨页传日期给DayColoumns

问题解答

核心问题根因

你触发无限重渲染的原因非常明确:你在ScreenPlanner组件的顶层作用域直接调用了setSelectedDate。
React组件每次渲染时都会执行组件内部所有顶层代码,setSelectedDate调用会更新state,state更新又会触发组件重新渲染,往复循环就触发了React的重渲染次数限制报错。
另外你最初的顾虑也不成立:React Navigation默认是懒加载路由页面的,只有你从SelectionScreen跳转过来的时候,ScreenPlanner才会开始渲染,此时route.params.date已经是用户选择完成的有效值,不需要提前渲染所有页面。

最优解决方案(无需额外维护state)

你已经可以通过route.params拿到传递过来的日期,完全不需要额外用state存储一份,直接使用即可,直接删掉冗余的state和顶层的setState调用就行。
修正后的代码如下:

const ScreenPlanner = ({ route }) => {
  // 直接从route.params拿日期,加个默认值兜底
  const selectedDate = route.params?.date || new Date();

  // 用useMemo缓存计算结果,只有selectedDate变化时才重新计算,避免不必要的性能损耗
  const flatListData = React.useMemo(() => {
    console.log("Date " + selectedDate);
    let dates = [];
    let data = [];
    let day = new Date(selectedDate);
    console.log("day " + day);

    let nextDay = new Date(day);
    // 生成未来7天的日期
    for (let i = 0; i < 7; i++) {
      dates.push(new Date(nextDay.setDate(day.getDate() + i)));
    }

    const locale = "de-DE";
    let options = {
      weekday: "short",
      year: "numeric",
      month: "long",
      day: "numeric",
    };
    dates.forEach((date) => {
      data.push({
        id: moment(date).format("DD/MM/YYYY"),
        day: date.toLocaleString(locale, options).substring(0, 3).toUpperCase(),
        number: date.getDate(),
      });
    });

    return data;
  }, [selectedDate]); // 依赖项是selectedDate,只有它变的时候才重新执行计算

  return (
    <View style={styles.screen}>
      <Header style={styles.header}>
        <Text style={styles.text}>{selectedDate}</Text>
      </Header>
      <View style={styles.containerPlanner}>
        <View style={styles.dayColoumns}>
          <FlatList
            horizontal={true}
            keyExtractor={(item, index) => item.id}
            data={flatListData}
            renderItem={(itemData) => (
              <DayColoumns
                id={itemData.item.id}
                day={itemData.item.day}
                number={itemData.item.number}
              />
            )}
          />
        </View>
        <View style={styles.containerHourRows}>
          <HourRows />
        </View>
      </View>
    </View>
  );
};

如果确实需要维护SELECTEDDATE状态的写法

如果后续你有在当前页面修改日期的需求,确实需要用state存储,那请把state更新逻辑放到useEffect里,只有当route.params.date变化的时候才更新state:

const [SELECTEDDATE, setSelectedDate] = useState(route.params?.date || new Date());

useEffect(() => {
  if(route.params?.date) {
    setSelectedDate(route.params.date);
  }
}, [route.params?.date]); // 仅当route.params.date变化时才执行更新

额外优化建议

  • 循环变量i请加let声明,避免变成全局变量污染
  • 日期格式化逻辑如果多处使用,可以抽成公共工具函数复用

内容的提问来源于stack exchange,提问作者Daniel Scho

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 23:27:02