Component 이벤트와 state

mk G·2023년 1월 18일
0

리액트

목록 보기
1/4

Props vs State

- Props : 상위 컴포넌트가 하위컴포넌트에게 명령(속성값 전달),read-only

- State : 하위 컴포넌트가 이벤트를 이용하여 상위컴포넌트의 값 변경 ,setState 사용

`import React, { Component } from 'react';
import Content from './Components/Content';
import Subject from './Components/Subject';
import Toc from './Components/Toc';

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: 'Helloooooooo ,React!!' },
      content: [
        { id: 1, title: 'HTML', desc: ' HTML is for information' },
        { id: 2, title: 'CSS', desc: 'CSS if for design' },
        { id: 3, title: 'Javascript', desc: 'JavaScript is for interactive' },
      ],
    };
  }
  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.content.length) {
        var data = this.state.content[i];
        if (data.id === this.state.selected_content_id) {
          _title = data.title;
          _desc = data.desc;
          break;
        }
        i = i + 1;
      }
    }
    console.log(_desc);
    return (
      <div>
        {/* Props, state변경시 Render 함수 재호출 다시 변경됨.*/}
        <Subject
          title={this.state.subject.title}
          sub={this.state.subject.sub}
          onChangePage={function () {
            this.setState({ mode: 'welcome' });
          }.bind(this)}
        ></Subject>
        {/* <Subject title="Node.js" sub="DB support!"></Subject> */}
        {/* <header>
          <h1>
            <a
              href="/"
              onClick={function (e) {
                //리액트에서는 이벤트함수 호출시 첫번째 매개변수값으로 event 가 전달됨.
                console.log(e);
                e.preventDefault(); //e객체의 함수: 이벤트 기본 동작을(페이지 전환) 막음.
                this.setState({ mode: 'welcome' }); //setState로 내부 변수 제어->렌더링
              }.bind(this)}
            >
              {this.state.subject.title}
            </a>
          </h1>
          {this.state.subject.sub}
        </header> */}
        <Toc
          onChagePage={function (id) {
            this.setState({
              mode: 'read',
              selected_content_id: Number(id),
            });
          }.bind(this)}
          data={this.state.content}
        ></Toc>
        <Content title={_title} desc={_desc}></Content>
      </div>
    );
  }
}

export default App;
// state값 올바르게 변경하는 방법
// 1. 함수 뒤에 .bind(this) 추가하기(이벤트 함수에서 this는 undefined)
//   <태그 onClick = {function(e){...}.bind(this)}></태그>

// 2.this.setState 함수 호출하여 state값 변경
//   this.setState({ mode: 'welcome' })

<Toc.js>

import React, { Component } from 'react';
import '../App.css';
class Toc extends Component {
  render() {
    let lists = [];
    let data = this.props.data; //컴포넌트는 내부적으로 this.props.data를 가짐
    let i = 0;
    while (i < data.length) {
      lists.push(
        <li key={data[i].id}>
          <a
            href={'/content/' + data[i].id}
            data-id={data[i].id} //HTML5부터 data-** 속성값을 이용하여 data 저장
            onClick={function (e) {
              //debugger;
              e.preventDefault(); //다른 페이지로 이동x
              this.props.onChagePage(e.target.dataset.id);
              //App 컴포넌트의 onChangePage(data-로 저장된 변수)함수 실행
            }.bind(this)}
          >
            {data[i].title}
          </a>
        </li>
      );
      i = i + 1;
    }
    return (
      <nav>
        <ul>{lists}</ul>
      </nav>
    );
  }
}
export default Toc;

0개의 댓글