익명의 개발노트

[Wecode 70일차] ref 본문

코딩일기/TIL

[Wecode 70일차] ref

캡틴.JS 2019. 8. 12. 23:41
반응형

1. 리액트에서 직접적으로 DOM을 건들고자할때 ref를 사용한다.

 

만약에 ref 사용하지 않고, document.getElementById 같은 함수를 사용한다면, 리액트 함수를 이용할 수 없는 단점이 있다.

 

버튼을 눌렀을때, 팝업창이 나오고, 팝업창을 제외한 다른 부분을 눌렀을때 닫아지는 것을 구현하고자 한다.

 

먼저 ref는 props로 넘길 수 없다.  webframeworks.kr/tutorials/react/react-dataflow

 

우선 game.js 라는 메인화면 안에 setting이라는 자식 커스텀 컴포넌트가 있다고 하자.

 

팝업(셋팅창) 버튼은 부모컴포넌트(game.js)에 있다. 버튼 클릭 시 부모의  state값이 바뀐다고했을때,

 

ref는 어디에 달아야하는가? 실제로 팝업창(셋팅창)의 html은 settings.js안에 있다. 

 

그럼 ref을 자식에게 달고, 자식이 클릭했을때, 값을 부모로 전달 해주면 된다.

 

스택오버플로우에 있는 예문

componentDidMount() {
    window.addEventListener('mousedown', this.handleOutsideClick);
    window.addEventListener('touchstart', this.handleOutsideClick);
  }

  componentWillUnmount() {
    window.removeEventListener('mousedown', this.handleOutsideClick);
    window.removeEventListener('touchstart', this.handleOutsideClick);
  }

  handleOutsideClick(e) {
    const { opend } = this.state;

    //이런식으로 지금 클릭한 공간이, 특정영역(팝업)에 포함되었는지 벗어났는지 확인
    if (!this.tooltipTrigger.contains(e.target) && opend) {
      this.setState({ opend: false });
    }
  }
  
  //jsx
  <div ref={node => { this.tooltipTrigger = node }}>

적용하기

//settings.js

 componentDidMount() {
       window.addEventListener('mousedown', this.handleOutsideClick);
       window.addEventListener('touchstart', this.handleOutsideClick);
  }
  
  componentWillUnmount() {
       window.removeEventListener('mousedown', this.handleOutsideClick);
       window.removeEventListener('touchstart', this.handleOutsideClick);
  }
  
  handleOutsideClick = (e) => {
     if (this.props.visible === false) return; //실제로 이로직은 this.props.visible가 true일때 나오게 되어있음.
     //이런식으로 지금 클릭한 공간이, 특정영역(팝업)에 포함되었는지 벗어났는지 확인
     if (!this.popup.contains(e.target)) {
        this.props.closeModal();
     }
  }
  
   render() {
        if (!this.props.visible)
        return '';
        
        return (
        	<..생략..>
             <div className="storage" ref={node => this.popup = node}>
        )
//game.js

 <Settings firebase={this.props.firebase}
           visible={this.state.isClickMenu}
           close={() => {this.setState({isClickMenu: false}) }}
           closeModal={() => {this.setState({isClickMenu: false}) }} />	    

2. 디버깅시 중요한 점(제임스 대표님께서 알려주신 내용)

  1) 버그발견시 무조건 코딩 금지.

  2) 가정을 세워라.(assumption)

  3) 가정을 세우고, 무엇때문에 안되는지 리스트 정리

  4) 우선순위 높은 순서대로 실행(되면 지우고, 지우다보면 남는 것때문에 버그가 날 확률이 높다)

반응형
Comments