简体   繁体   中英

Chart Duplicates because of useEffect re-render

I have a parent component which I'm using to pass props (ie backgroundColor ) to child component( <LivePortfolioGraph /> ).

In my child component I have a dependency array that re-renders every time color is changed from parent ie ( props.backgroundColor ).

Now i don't want want to create a new graph on every render, if chart exist just apply color options.

Really appreciate any help. Thanks.

Parent Component

    const Main = (props) => {
    
      const [backgroundColor, setbackgroundColor] = useState('#141d27');
    
     const g = useRef(null);
    
    return (
    
     <div ref={g} className="FinancialChartIntro" >
    
        <LivePortfolioGraph g={g} backgroundColor={backgroundColor} />
    
        </div> 
    
    )
}

Child Component

const  LivePortfolioGraph = (props) => {

const [width, setWidth] = useState(0);
const [height, setHeight] = useState(0);


useEffect( ()=> {

const handleStyle = _debounce(() => { chart.applyOptions({layout: {backgroundColor:props.backgroundColor  } }); }, 100)

window.addEventListener("input", handleStyle); 


const chart = createChart(props.g.current, options );


// Clean Up
return () => {


window.removeEventListener('input', handleStyle);

}



}, [props.backgroundColor])

第一次渲染

当我改变颜色时,另一个图表显示了以前的 defaultValue

创建的元素

UPDATE I have found a hacky way to remove child nodes( chart dups). It slows down the page like crazy I dont wanna even use it. STILL TRYING to find another solution.

 > if(props.g.current.childNodes.length > 2) { > props.g.current.removeChild(props.g.current.childNodes[2]) }

I think your issue is the single useEffect hook is doing "too much" work. Move the chart value into a React ref and use the effect hook to update the color/styling.

const  LivePortfolioGraph = (props) => {
  const [width, setWidth] = React.useState(0);
  const [height, setHeight] = React.useState(0);

  const chart = React.useRef(createChart(props.g.current, options);

  React.useEffect(()=> {
    const handleStyle = _debounce(() => {
      chart.current.applyOptions({
        layout: {
          backgroundColor: props.backgroundColor,
        },
      });
    }, 100);

    window.addEventListener("input", handleStyle); 
    // Clean Up
    return () => {
      window.removeEventListener('input', handleStyle);
    }
}, [props.backgroundColor]);

Just perform a check to see if the chart has already be instantiated.

Here is a snippet of a hook I created to setup the chart useSetupChart

  useEffect(() => {
    if (!chartContainerRef.current || chart) return;

    setChart(createChart(chartContainerRef.current));
  }, [chartContainerRef.current, chart]);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM