🔗 생활코딩 React

1. 이벤트, state, props 그리고 render 함수

  • 이벤트, state, props가 상호작용하면서 애플리케이션에 역동성 부여
  • props나 state가 수정되면 해당되는 컴포넌트의 render 함수가 재호출됨
    👉 화면이 다시 그려짐
// Subject.js (제목에 링크 추가)
<h1><a href="/">{this.props.title}</a></h1>
// App.js
constructor(props){    // 'mode'와 'welcome' state 추가
    super(props);
    this.state = {
      mode: "welcome",
      subject: {title: 'WEB', sub: 'World Wide Web!'},
      welcome: {title: 'Welcome', desc: 'Hello, React!'},
      contents: [...]
    }
  }
render() {    // Content 컴포넌트에 표시될 '_title', '_desc'를 'mode' 값에 따라 설정
    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'){    // 추후 보완 필요
      _title = this.state.contents[0].title;
      _desc = this.state.contents[0].desc;
    }
    return (
      <div className="App">
        ...
        <Content title={_title} desc={_desc}></Content>
      </div>
    );
  }

2. 이벤트 설치

  • preventDefault(): 이벤트가 가진 기본 동작을 하지 못하도록 막는 함수
// App.js
render() {
    ...
    return (
      <div className="App">
        // jsx 주석
        {/* {<Subject 
          title={this.state.subject.title} 
          sub={this.state.subject.sub}>
        </Subject>} */}
        <header>
          <h1><a href="/" onClick={function(e){
            console.log(e);
            e.preventDefault();
          }}>{this.state.subject.title}</a></h1>
          {this.state.subject.sub}
        </header>
        ...
      </div>
    );
  }


태그에서 바로 함수 선언해서 이벤트 설치가 가능하다니 신기할 따름

3. 이벤트에서 state 변경하기

  • 이벤트가 실행되는 함수 안에서 this는 아무런 값도 세팅되지 않은 상태
    👉 bind(this)로 현재 컴포넌트를 this로 사용 가능!
  • state 값을 바꾸려면 setState() 함수 이용
// App.jsx
<header>
  <h1><a href="/" onClick={function(e){
        ...
        // this.state.mode = 'welcome';
        this.setState({
          mode:'welcome'
        });
      }.bind(this)}>{this.state.subject.title}</a></h1>
  {this.state.subject.sub}
</header>

4. 이벤트 bind 함수 이해하기

  • render() 함수 안에서 this 값은 render() 함수가 속한 컴포넌트를 가리킴
  • bind 함수
var obj = {name:'bono'};

function bindTest(){
    console.log(this.name);
}
bindTest();    // 값이 없음(this에 아무 값도 설정되어 있지 않으므로

// bind 함수로 obj를 this로 설정해서 새로운 함수 생성
var bindTest2 = bindTest.bind(obj);    
bindTest2();    // bono 출력

5. 이벤트 setSate 함수 이해하기

  • 동적으로 state 값을 변경할 때 사용

6. 컴포넌트 이벤트 만들기 1

  • 컴포넌트에 props로 이벤트 생성하여 전달
  • bind() 함수로 컴포넌트 연결
  • 제목(WEB)을 클릭하면 modewelcome으로 변경
// App.js
<Subject 
  ...
  onChangePage={function(){
    this.setState({mode:'welcome'});
  }.bind(this)}>
</Subject>
// Subject.js
<header>
  <h1><a href="/" onClick={function(e){
        e.preventDefault();
        this.props.onChangePage();
      }.bind(this)}>{this.props.title}</a></h1>
  {this.props.sub}
</header>

7. 컴포넌트 이벤트 만들기 2

  • 목차의 요소를 클릭하면 moderead로 변경
// App.js
<TOC onChangePage={function(){
    this.setState({mode:'read'});
  }.bind(this)} 
  data={this.state.contents}>
</TOC>
// TOC.js
while(i < data.length){
  lists.push(
    <li key={data[i].id}>
      <a 
        href={"/content/"+data[i].id}
        onClick={function(e){
          e.preventDefault();
          this.props.onChangePage();
        }.bind(this)}
        >{data[i].title}</a>
    </li>);
  i = i + 1;
}

8. 컴포넌트 이벤트 만들기 3

  • 목차의 요소를 클릭하면 해당 요소의 내용 출력
// App.js
constructor(props){
  super(props);
  this.state = {
    mode:"read",
    selected_content_id:2,    // 기본값은 2
    ...
  }
}
  render() {
    var _title, _desc = null;
    if(this.state.mode === 'welcome'){
      ...
    }else if(this.state.mode === 'read'){
      var i = 0;
      // state.contents의 id와 state.selected_content_id가 일치하는 정보 세팅
      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;
      }
    }
    return (
      <div className="App">
        ...
        <TOC onChangePage={function(id){    // e.target.dataset.id
          this.setState({
            mode:'read',
            selected_content_id:Number(id)    // id를 숫자로 바꿔서 세팅
          });
        }.bind(this)} 
        data={this.state.contents}>
        </TOC>
        ...
      </div>
    );
  }
// TOC.js
<li key={data[i].id}>
  <a 
    href={"/content/"+data[i].id}
    data-id={data[i].id}  // 이벤트 객체(e) - target - dataset - id 값 세팅
    onClick={function(e){
      e.preventDefault();
      this.props.onChangePage(e.target.dataset.id);    // 세팅한 값 가져옴
    }.bind(this)}
    >{data[i].title}</a>
</li>

🤷‍♀️
이게,,,뭐죠,,,?