首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >react本机呈现-html:“您似乎在短时间内更新了Y组件的X支柱.”

react本机呈现-html:“您似乎在短时间内更新了Y组件的X支柱.”
EN

Stack Overflow用户
提问于 2021-08-28 16:09:31
回答 2查看 6.5K关注 0票数 13

注:我是react-native-render-html__的作者。这个问题是为了教育目的,https://stackoverflow.blog/2011/07/01/its-ok-to-ask-and-answer-your-own-questions/

我在一个RenderHtml组件中呈现WebDisplay组件,如下所示:

代码语言:javascript
复制
import * as React from 'react';
import {ScrollView, StyleSheet, Text, useWindowDimensions} from 'react-native';
import RenderHtml from 'react-native-render-html';

const html = '<div>Hello world!</div>';

function WebDisplay({html}) {
  const {width: contentWidth} = useWindowDimensions();
  const tagsStyles = {
    a: {
      textDecorationLine: 'none',
    },
  };
  return (
    <RenderHtml
      contentWidth={contentWidth}
      source={{html}}
      tagsStyles={tagsStyles}
    />
  );
}

export default function App() {
  const [isToastVisible, setIsToastVisible] = React.useState(false);
  React.useEffect(function flipToast() {
    const timeout = setTimeout(() => {
      setIsToastVisible((v) => !v);
    }, 30);
    return () => {
      clearTimeout(timeout);
    };
  });
  return (
    <ScrollView contentContainerStyle={styles.container}>
      <WebDisplay html={html} />
      {isToastVisible && <Text>This is a toast!</Text>}
    </ScrollView>
  );
}

const styles = StyleSheet.create({
  container: {
    flexGrow: 1,
  },
});

为什么我会收到这样的警告,这意味着什么,以及如何修正它?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-08-28 16:09:31

通常,此警告会在下列情况下显示:

  • 父组件(当前为App)经常更新,并导致WebDisplay组件重新呈现。在提供的片段中,每30毫秒一次;
  • 传递给RenderHTML的至少一个支柱在每个重呈现之间都是参照不稳定的。在所提供的片段中,每次重呈现时都会更改tagsStyles引用。

注意,在每次更新由App挂钩引起的useEffect组件之间,传递给WebDisplayhtml支柱没有变化。但是WebDisplay被重新呈现,因为它不是“纯”的。

出于这个原因,一个非常简单的解决方案是将WebDisplay封装在React.memo中。

代码语言:javascript
复制
const WebDisplay = React.memo(function WebDisplay({html}) {
  const {width: contentWidth} = useWindowDimensions();
  const tagsStyles = {
    a: {
      textDecorationLine: 'none',
    },
  };
  return (
    <RenderHtml
      contentWidth={contentWidth}
      source={{html}}
      tagsStyles={tagsStyles}
    />
  );
});

您可以了解更多关于这种技术的在正式文件中

Note:“纯”术语来自React PureComponent类。我认为React.pure不会像React.memo那样模棱两可,因为我们现在使用“回忆录”来指定应用于组件和道具的优化技术,这可能会让人感到困惑。我更喜欢为组件保留“纯”术语,为道具保留“回忆录”。

另一种解决方案是将tagsStyles移出WebDisplay函数体。在这种情况下,它将只实例化一次,并成为引用稳定的。因为RenderHtml本身是纯的,所以它不会重新呈现自己的子组件,因此警告应该消失:

代码语言:javascript
复制
const tagsStyles = {
  a: {
    textDecorationLine: 'none',
  },
};

function WebDisplay({html}) {
  const {width: contentWidth} = useWindowDimensions();
  return (
    <RenderHtml
      contentWidth={contentWidth}
      source={{html}}
      tagsStyles={tagsStyles}
    />
  );
};

Note:移动任何不依赖于功能组件主体之外的任何其他状态或支持的道具是一个很好的习惯。

最后,如果您的用例涉及到tagsStyles (取决于一个道具),您可以使用React.useMemo回溯它。

代码语言:javascript
复制
function WebDisplay({html, anchorColor}) {
  const {width: contentWidth} = useWindowDimensions();
  const tagsStyles = React.useMemo(
    () => ({
      a: {
        color: anchorColor,
        textDecorationLine: 'none',
      },
    }),
    [anchorColor],
  );
  return (
    <RenderHtml
      contentWidth={contentWidth}
      source={{html}}
      tagsStyles={tagsStyles}
    />
  );
}

关于这个钩子在正式文件中的更多信息。

如果你还没有一个清晰的心理模型来解释组件更新是如何反应的,我建议你通过这些阅读来提高你的技能:

票数 19
EN

Stack Overflow用户

发布于 2022-06-15 23:27:53

把这个道具,enableExperimentalBRCollapsing={true},从<RenderHtml />上移走,为我工作。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68966120

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档