React(bind, setState) - 4

大 炫 ·2020년 8월 3일
0

react

목록 보기
4/8
post-thumbnail

이번에는 bind 와 setState를 설명하기 전에 짜고있는 코드를 한번 쭉 복기하고 bind와 setState를 설명해보겠다.

가장 상위 Component

class App extends Component {
  constructor(props){
    super(props);
    this.state = {
      mode:'read',
      selected_content_id:2,
      subject:{title:'Web', sub:'World Wide Web!'},
      welcome:{title:'welcome', desc:'Hello, React !!'},
      contents :[
        {id:1, title:'HTML', desc:'HTML is for informatrion'},
        {id:2, title:'CSS', desc:'CSS is design.'},
        {id:3, title:'JS', desc:'JS is for interactive'}
      ]
    }
  }

가장 부모의 Component인 클래스 App에 state값을 설정하는 모습이다. state값에는
mode값이 변경됨에 따라 content의 내용이 변경되는 mode값이고
selected_content_id(2는 값은 그냥해놓은값)값은 TOC(HTML,CSS,JS 하이퍼링크가 부여된 코드)가 클릭되는 이벤트의 따라 state의 contents에 부여해놓은 id값이 변경되는데 그에 맞는content의 내용이 표시되게끔 설정해둔 값이다.
welcome은 mode값이 welcome으로 변경될 때 content의 표시될 title과 sub를 나타낸것이다.

render함수

render() {
   var _title, _desc = null;
   if(this.state.mode === 'welcome'){
     _title = this.state.welcome.title;
     _desc = this.state.welcome.desc;
   }
   else if(this.state.mode === 'read'){
     var i = 0;
     while(i < this.state.contents.length){
       var data = this.state.contents[i];
       if(data.id === this.state.selected_content_id) {
         _title = data.title;
         _desc = data.desc;
         break;
       }
       i = i + 1;
     }
   }

어떤 html을 그릴것인가 정의하는 render함수, 그곳엔 mode값이 변경될때마다 들어갈 _title, _desc를 아직 정해지지않은 null값으로 정의해두고 if(this.state.mode) 즉 mode값이 어떤 값일 때 그곳에 _title과 _desc에 어떤값을 부여할 것이다. 라는 규칙이다.
mode값이 read값이 될때는 while문과 if문이 중첩되는데 while문은 contents의 길이만큼 반복될 것인데 반복될 동안 contents를 data라는 변수에 담아 data.id와 selcected_content_id가 일치할경우 _title,_desc에 값을 부여하고 break를 걸어 빠져나오게한다.

return (
     <div className="App">
       <Subject
       title={this.state.subject.title}
       sub={this.state.subject.sub}
       onChangePage={function(){
         this.setState({mode:'welcome'});
       }.bind(this)}
     >
     </Subject>
       <TOC
         onChangePage={function(id){
         this.setState({
           mode:'read',
           selected_content_id : Number(id)
         });
       }.bind(this)}
       data={this.state.contents}
       ></TOC>
       <Content title={_title} desc={_desc}></Content>
     </div>
   );
 }
}

여기서는 다른부분은 간단한내용이라 onChangePage와 setState, bind(this)에 대해서만 얘기하겠다.
우선 Subject안에 헤더(또는 타이틀, 로고 등)를 클릭했을 때 mode의 값이 welcome으로 바뀌는 setState를 onChangePage로 정의했다.
Subject내용은 다음의 Component를 보겠다.

Subject Component

class Subject extends Component{
    render(){
      return (
        <header>
          <h1><a href="/" onClick={function(e){
            e.preventDefault();
            this.props.onChangePage();
          }.bind(this)}>{this.props.title}</a></h1>
          {this.props.sub}
        </header>
      );
    }
  }

즉 Web이라는 h1태그의 a태그를 onClick했을 때 실행되는 함수에 앞서 정의해놓은 onChangePage를 실행하라 라고 작성한것이 onClick={} 안에 모두 들어있다.

그래서 bind, setState 란 ?

앞서 return되는 값들의 코드중 대부분의 this는 상위의 Component인 App을 가르키고,

	function(id){
          this.setState({
            mode:'read',
            selected_content_id : Number(id)
          });
        }.bind(this)

this.setState의 this는 그 상위인 function을 뜻한다. 여기서 만약 .bind(this)만 제거하면 어떤 에러가 날까 ?

Web이라는 타이틀을 클릭했을 때
TypeError: this.setState is not a function 에러가 나는것을 볼수있다.
this.setState({})로 함수작성을 했는데 함수로 인식을 못한다는 내용같다. 이때 위의 코드와같이 bind(this)를 추가해준다면 왜 정상실행이 될까? 로 나는 bind와 setState를 유추했다.
bind는 묶는다는 뜻인데 즉 bind(this) = 묶는함수(App)
아직 머리속에서 완벽히 이해를 못해 정리가 안됬다. 다된다면 수정하겠다!

profile
대현

0개의 댓글