【问题标题】:Components keeps Rerendering in react-native组件在 react-native 中保持重新渲染
【发布时间】:2021-10-28 22:26:15
【问题描述】:

我有一个组件,它的性能很差。调试的时候发现这两个子组件无缘无故一直在重新渲染。

谁能帮我看看这里有什么问题。在我的日志中,我收到了 Rendering CategoriesRendering Queries一遍遍

这是我的实现:

const categories = useMemo(() => ({
chefs: {
  name: 'Chefs',
  title: getMessageByKey('explore.chefs'),
  image: ChefsCategory,
  available: true,
},
recipes: {
  name: 'Recipes',
  title: getMessageByKey('explore.recipes'),
  image: RecipesCategory,
  available: true,
},
products: {
  name: 'Products',
  title: getMessageByKey('explore.products'),
  image: ProductsCategory,
  available: false,
},
buisness: {
  name: 'Buisness',
  title: getMessageByKey('explore.buisness'),
  image: BuisnessCategory,
  available: false,
},
}))



const queries = useMemo(() => ({
    trending: {
      name: 'Trending',
      title: getMessageByKey('explore.trending'),
      image: <FireFilter style={styles.queryImage} />,
      selectedImage: <FireWhiteFilter style={styles.queryImage} />,
      dataFunc_Chefs: getTrending_Chefs,
      dataFunc_Recipes: getTrending_Recipes,
    },
    new: {
      name: 'New',
      title: getMessageByKey('explore.new'),
      image: <LightningFilter style={styles.queryImage} />,
      selectedImage: <LightningWhiteFilter style={styles.queryImage} />,
      dataFunc_Chefs: getNew_Chefs,
      dataFunc_Recipes: getNew_Recipes,
    },
    top: {
      name: 'Popular',
      title: getMessageByKey('explore.popular'),
      image: <HeartFilter style={styles.queryImage} />,
      selectedImage: <HeartWhiteFilter style={styles.queryImage} />,
      dataFunc_Chefs: getPopular_Chefs,
      dataFunc_Recipes: getPopular_Recipes,
    },
    verified: {
      name: 'Verified',
      title: getMessageByKey('explore.verified'),
      image: <VerifiedFilter style={styles.queryImage} />,
      selectedImage: <VerifiedWhiteFilter style={styles.queryImage} />,
      dataFunc_Chefs: getVerified_Chefs,
      dataFunc_Recipes: getVerified_Recipes,
    },
  }))
...

<View style={styles.categoriesContainer}>
        {console.log('Rendering Categories')}
        {
          Object.values(categories).map((category) => {
            return (
              <View style={styles.categoryContainer} 
                key={category.name} 
              >
                <TouchableWithoutFeedback
                  onPress={category.available ? ()=> handleCategoryClick(category.name) : () => showToast({type: 'error', text1: 'Coming Soon', text2: 'This feature is Coming Soon'})}
                >
                  <Image
                    style={[styles.categoryImage, selectedCategory === category.name ? styles.selectedCategory : '']}
                    source={ category.image }
                  />
                </TouchableWithoutFeedback>
                <Text style={[styles.categoryName, {color: theme.textColor}]}>{category.title}</Text>
              </View>
            )
          }
        )}
      </View>

      <View style={styles.queriesContainer}>
      {console.log('Rendering Queries')}
        {
          Object.values(queries).map(query => {
            return (
              <TouchableWithoutFeedback
                key={query.name}
                onPress={()=> handleQueryClick(query)}
              >
                <View style={[styles.queryContainer, selectedQuery === query.name ? styles.querySelected : '']}>
                  <Text style={selectedQuery === query.name ? styles.queryTextSelected : styles.queryText}>{query.title}</Text>
                  {
                    selectedQuery === query.name ? 
                      query.selectedImage : 
                      query.image
                  }
                </View>
              </TouchableWithoutFeedback>
            )
          }
        )}
      </View>

【问题讨论】:

    标签: reactjs react-native rerender


    【解决方案1】:

    您在两个 useMemo 中都缺少依赖项数组。默认情况下,如果没有依赖数组,useMemo 将在每次状态更改时运行。

    如果您希望这些只被评估一次 - 在挂载时,请添加一个空的依赖数组作为第二个参数。

    如果您希望每次变量更改时都对它们进行评估,请将所有变量添加到依赖数组中。

    【讨论】:

    • 还是一样,组件一直在重新渲染
    • 是在状态改变时重新渲染还是无限地重新渲染?如果它无限地重新渲染,请检查两件事,1. 在返回对象之前,在 useMemo 中移动 console.log("Rendering queries") 和 console.log("Rendering Categories")。如果 console.logs 无限打印, 2. 添加一个 useEffect(() => { console.log("Mounting") }, [] 来检查父级中是否有东西导致它一次又一次地挂载
    • 我在 useMemo 和 useEffect 中添加了两个日志,并且都只记录一次。所以,问题不存在
    • 太棒了!然后我们知道除了类别或查询之外,状态的某些部分正在发生变化。您需要共享组件主体的其余部分以供我们识别。
    猜你喜欢
    • 2021-01-02
    • 2021-11-18
    • 1970-01-01
    • 2016-06-13
    • 2018-12-16
    • 1970-01-01
    • 2019-02-26
    • 2021-06-07
    • 1970-01-01
    相关资源
    最近更新 更多