【问题标题】:Why do I have to too many re-renders and how I can solve this?为什么我必须进行太多的重新渲染以及如何解决这个问题?
【发布时间】:2021-10-24 00:42:25
【问题描述】:

我需要将来自我的 SelectionScreen 的日期输入提供给不同的屏幕 (ScreenPlanner) 以将其提供给组件 DayColumns


但是在启动应用程序时所有屏幕都已经渲染,所以我不能等到用户输入来渲染组件或整个屏幕,或者我可以吗? 在我的代码中,我使用状态来重新渲染带有输入数据的组件。 prepareData 返回Flatlist 的数据。

根据我的 console.logs() 正确处理了数据,但它给了我这个错误: 错误:重新渲染过多。 React 限制了渲染的数量以防止无限循环。 此错误位于: 在 ScreenPlanner 中(在 SceneView.tsx:126) 在静态容器中 ...... 我不确定为什么我处于无限循环中,但我认为它与 .我该如何解决这个问题,或者有没有比使用state 更好的方法。我尝试使用await 来等待输入,但效果不佳。

const ScreenPlanner = ({ route }) => {
  const [SELECTEDDATE, setSelectedDate] = useState(new Date());

  setSelectedDate(route.params.date);
  console.log(SELECTEDDATE)

  const prepareData = (SELECTEDDATE) => {
    console.log("Date " + SELECTEDDATE);
    let dates = [];
    let data = [];
    let day = new Date(SELECTEDDATE);
    console.log("day " + day);

    let nextDay = new Date(day);
    // next 7 days:
    for (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(), //day: date.toLocaleString("en-us", { weekday: "short" })
        number: date.getDate(),
      });
    });

//console.log(data);
    return data;
  };

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

我愿意接受任何提示和帮助,因为我是 React Native 的新手。

【问题讨论】:

  • setSelectedDate(route.params.date); 在渲染中无条件更新状态。

标签: javascript reactjs react-native expo jsx


【解决方案1】:

每次呈现ScreenPlanner 时,您的代码都会执行setSelectedDate(route.params.date);,这会导致ScreenPlanner 组件再次呈现...

这应该可行:

const ScreenPlanner = ({ route }) => {
  const [SELECTEDDATE, setSelectedDate] = useState(new Date());

  React.useEffect(() => {

      setSelectedDate(route.params.date);

  }, [route.params.date]);

  console.log(SELECTEDDATE)

...

像这样,useEffect 里面的代码只有在route.params.date 改变时才会被调用。

【讨论】:

  • 是的,它对我有用。我认为它会更复杂 x3 非常感谢。
【解决方案2】:

你在外面调用函数

setSelectedDate(route.params.date);

import {useEffect} from 'react';

并在组件内部使用

useEffect(() => {
  setSelectedDate(route.params.date);
  console.log(SELECTEDDATE)
}, []);

【讨论】:

    猜你喜欢
    • 2021-01-10
    • 1970-01-01
    • 1970-01-01
    • 2016-09-04
    • 1970-01-01
    • 2014-02-16
    • 2021-11-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多