Notes: I'm the author of react-native-render-html. This question is for educational purposes, in compliance with StackOverflow policy.
I am rendering RenderHtml component in a WebDisplay component like so:
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,
},
});
Why am I getting this warning, what does it mean and how to fix it?
Usually, this warning shows up when:
App) component updates very often and causesWebDisplaycomponent to re-render. In the provided snippet, every 30 milliseconds;RenderHTMLis referentially unstable between each re-render. In the provided snippet,tagsStylesreference changes on every re-render.Notice that between every update of the
Appcomponent caused by theuseEffecthook, thehtmlprop passed toWebDisplayis unchanged. ButWebDisplayis re-rendered anyway because it is not "pure".For this very reason, a pretty straightforward solution is to wrap
WebDisplayinReact.memo:You can learn more about this technique in the official documentation.
Another solution is to move
tagsStylesoutside theWebDisplayfunction body. In that case, it will be instantiated only once and become referentially stable. BecauseRenderHtmlitself is pure, it won't re-render its own subcomponents and the warning should disappear:Finally, if your use case involves
tagsStylesdepending on a prop, you could memoize it withReact.useMemo:More information on this hook in the official documentation.
If you still don't have a clear mental model of how component updates work in React, I suggest those readings to enhance your skills: