IT,프로그래밍/React.js

[생활코딩] 4# 리액트 공부

컴포넌트 이벤트

이번에는 컨텐츠를 누르면 그 컨텐츠에 해당하는 정보를 읽을수 있도록 만들어준다

  constructor(props){//랜더하기전에 초기화 해주고 싶은코드는 constructor 안에 써야한다.
    super(props);
    this.state = {
      mode:"read",
      selected_content_id :2,
      subject:{title : 'WEB', sub : 'world wide web'},
      welcome: {title: 'welcome',desc: 'welcome react'},
      contents :[
        {id : 1, title : 'HTML', desc : 'HTML is for ...'},
        {id : 2, title : 'CSS', desc : 'CSS is for ...'},
        {id : 3, title : 'JavaScript', desc : 'JavaScript is for ...'}
      ]
    }
  }
  

먼저 생성자에서 만들어주는 state 객체에 selected_content_id 라는 값을 새롭게 선언해준다

이 selected_content_id의 역활은 contents 중 어떤 id 를 가진 컨텐츠가 선택되었는지를 분기해 주는 변수이다.

이경우 읽기 모드가 되도록 mode ==='read' 일때의 분기 처리를 해준다.

 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;
      }
    }
    

소스를 해석해 보자면

mode 가 read 로 진입하면 render() 를 할때에

this.state.contents.length 만큼 while 을 실행시켜준다.

이후에

    var data = this.state.contents[i];
        if(data.id === this.state.selected_content_id){
          _title = data.title;
          _desc = data.desc;
          break;
        }
        i=i+1;
      }
      

에서 아까 선택된 this.state.selected_content_id 와 같은 date 의 id 가

선택이 되어있을때 title 과 desc 에 출력할 데이터를 넣어준다.

조건이 성립이되면 while 을 빠져나오도록 break; 를 추가해준다

        while (i < data.length) {
            lists.push(
                <li key={data[i].id}>
                    <a href={"/content/"+data[i].id}
                        data-id = {data[i].id}
                        onClick = {function (e) {
                            debugger;
                            e.preventDefault();
                            this.props.onChangePage();
                        }.bind(this) }>{data[i].title}
                    </a>
                </li>);
            i = i+1;
        }
        

여기에서 e 를 console 에찍어보면 target 에서 a 태그를 가리킨다.

그 a 태그의 속성중 data-set 을 가보면

id 값으로 1 이 들어가 있는데

data-id = {data[i].id}data-idd = {data[i].id} 로 변경한다면

id :1 이 아닌 idd : 1 로변경이 된다 즉, data- 뒤에 붙는 단어가 키값이된다.

그렇다면 이것을 어떻게 사용할수 있을까?

바로. e.target.dataset.id 쓴다면 현재 클릭된 객체의 id 값을 가져올수 있고

onclick 이벤트를 App.js 에 있는 onChangePage() 함수의 파라미터로 넣어서

클릭에 따라 다른 내용과 타이틀이 나오게 만들어 줄수 있다!!

TOC.js

            lists.push(
                <li key={data[i].id}>
                    <a href={"/content/"+data[i].id}
                        data-id = {data[i].id}
                        onClick = {function (e) {
                            e.preventDefault();
                            this.props.onChangePage(e.target.dataset.id);
                        }.bind(this) }>{data[i].title}
                    </a>
                </li>);
                

onChangePage 의 파라미터로 id 값을 넘겨주면

App.js

      <TOC         
      onChangePage={function(id){
        debugger;
        this.setState({
          mode:'read',
          selected_content_id : id
        })
        }.bind(this)}
        data={this.state.contents}></TOC>
        

App 의 태그에서 선언한 함수의 id 값으로 들어가게된다.

따라서 render() 마다 누른 카테고리의 컨텐츠를 출력시킬수있다.

2번째 방법 .

            lists.push(
                <li key={data[i].id}>
                    <a href={"/content/"+data[i].id}
                        onClick = {function (id, e) {
                            e.preventDefault();
                            this.props.onChangePage(id);
                        }.bind(this, data[i].id) }>{data[i].title}
                    </a>
                </li>);
                

*bind 에 2번째 인자로 주게되면 *

function (id, e) 에서 앞에서 부터 인자가 들어가게된다.