Closed Ankcorn closed 3 years ago
No fix on this yet?
I don't know if this could help but I used the componentShouldUpdate() lifecycle hook to stop the re-rendering of the word cloud. In my case, I was passing the data used by the word cloud as props. So I return false in the componentShouldUpdate() lifecycle hook if the data is equal. Word of caution though, you must ensure that you are comparing only the text and value keys because other keys (e.g., padding, font, x, y, etc.) seem to be automatically added by the WordCloud component. Let me know if this helps. Thanks!
We resolved this issue using PureComponents. It disabled re-rendering content on any click event. We made our component(parent) PureComponent where we are calling WordCloud component
As of version 0.10.1, <WordCloud />
has been wrapped by React.memo()
and deep equal comparison under the hood to avoid unnecessary re-render. All you need to do is to make your function props deep equal comparable using useCallback()
:
import React, { useCallback } from 'react';
import { render } from 'react-dom';
import WordCloud from 'react-d3-cloud';
import { scaleOrdinal } from 'd3-scale';
import { schemeCategory10 } from 'd3-scale-chromatic';
function App() {
const data = [
{ text: 'Hey', value: 1000 },
{ text: 'lol', value: 200 },
{ text: 'first impression', value: 800 },
{ text: 'very cool', value: 1000000 },
{ text: 'duck', value: 10 },
];
const fontSize = useCallback((word) => Math.log2(word.value) * 5, []);
const rotate = useCallback((word) => word.value % 360, []);
const fill = useCallback((d, i) => scaleOrdinal(schemeCategory10)(i), []);
const onWordClick = useCallback((word) => {
console.log(`onWordClick: ${word}`);
}, []);
const onWordMouseOver = useCallback((word) => {
console.log(`onWordMouseOver: ${word}`);
}, []);
const onWordMouseOut = useCallback((word) => {
console.log(`onWordMouseOut: ${word}`);
}, []);
return (
<WordCloud
data={data}
width={500}
height={500}
font="Times"
fontStyle="italic"
fontWeight="bold"
fontSize={fontSize}
spiral="rectangular"
rotate={rotate}
padding={5}
random={Math.random}
fill={fill}
onWordClick={onWordClick}
onWordMouseOver={onWordMouseOver}
onWordMouseOut={onWordMouseOut}
/>
);
);
See https://github.com/Yoctol/react-d3-cloud#how-to-avoid-unnecessary-re-render
For every onclick event on the page the wordcloud is displayed on all the words shuffle about a bit.
The data prop is provided from redux but does not change prompting a re render of the chart
If I have implemented it wrong let me know.
Thanks