그래프가 중첩되는 이슈 - boostcamp-2020/Project15-A-Client-Based-Formula-Editor GitHub Wiki
지은님이 맡으신 그래프 라이브러리 기능 추가에서 나타난 이슈를 함께 해결했습니다.
Desmos
라이브러리를 사용하여 그래프를 우선 추가했습니다.
Docs에서는 그래프를 추가할 때 추가할 영역을 div 태그로 만들고 elementId로 해당 DOM을 가져옵니다.
<script>
var elt = document.getElementById('calculator');
var calculator = Desmos.GraphingCalculator(elt);
calculator.setExpression({ id: 'graph1', latex: 'y=x^2' });
</script>
React에서는 DOM에 직접 접근할 때 사용하는 document.getElementById를 지양하기 때문에 React식으로 변경할 필요가 있었습니다.
react의 ref를 사용하여 참조하도록 변경했습니다.
const graphRef = useRef();
const calculator Desmos.GraphingCalculator(graphRef.current, [...options])
calculator.setExpression({ id: 'graph1', latex: 'y=x^2' });
rnder(<Graph ref={graphRef}/>);
GraphingCalculator는 DOM에서 제거될 때마다 GraphingCalculator.destory()를 호출하여 제거해야할 필요가 있습니다.
React에서는 state가 변경되면 자동으로 렌더링되기때문에 기존 그래프에 중첩적으로 그래프가 추가되는 문제가 발생했습니다.
이 문제를 해결하기 위해 컴포넌트가 제거되는 시점을 알기위해 react의 생명주기를 공부하게 되었습니다.
찾는 시점이 componentWillUnmount
라는 것을 알게되었습니다.
참고: velopert 생명주기
하지만, 해당 메소드들은 클래스형 컴포넌트에서만 생성가능했고, 함수형에서 사용하는 방법을 찾아야했습니다.
여러가지 시도 끝에 useEffect
를 사용하면 hook으로 라이프 사이클을 관리할 수 있다는 것을 알게되었습니다.
참고: useEffect로 life cycle 관리하기
useEffect
로 최종 작성한 코드
useEffect(() => {
const calculator = Desmos.GraphingCalculator(graphRef.current, {
expressions: false,
settingsMenu: false,
zoomButtons: false,
trace: false,
border: false,
showGrid: false,
});
calculator.setExpression({
id: 'graph1',
latex,
});
return () => calculator.destroy();
}, [visible, latex]);