본문 바로가기
  • think normal
새로워지기/서른의 생활코딩

[생활코딩 따라가기] React 15 props와 state

by 청춘만화 2019. 5. 26.

https://www.youtube.com/watch?v=rOpg2KUPW2M&list=PLuHgQVnccGMCRv6f8H9K5Xwsdyg4sFSdi&index=16

 

1. 개요

State  내부에서 컴포넌트를 구현하기 위한 요소(개발자가 내부 구현하기 위해 조작되는 내부 개발 문법 )
Props 외부에서 컴포넌트를 사용하기 위한 요소(사용자가 컴포넌트를 사용하기 위한 인터페이스)

https://i.stack.imgur.com/wqvF2.png

  • State can be changed (Mutable)
  • Whereas Props can't (Immutable)

 

 

2. 이번 수업의 첫번째 목표

아래 노출되어 있는 속성 을 감춘다. 

<Subject title="WEB" sub="world wide web !"></Subject>

 

1) app.js (before)

import React, {Component} from 'react';
import './App.css';

//분리된 컴포넌트들 import 
import Subject from "./component/Subject"
import TOC from "./component/TOC"
import Content from "./component/Content"

//*컴포넌트들이 '들어가는(나열되는)' 영역
class App extends Component{
  render(){
    return (
      <div className="App">
         <Subject title="WEB" sub="world wide web !"></Subject>
         <TOC></TOC>
         <Content title="HTML" desc="HTML is HyperText "></Content>
      </div>
    );
  }
}

export default App;

2) app.js (after)

import React, {Component} from 'react';
import './App.css';

//분리된 컴포넌트들 import 
import Subject from "./component/Subject"
import TOC from "./component/TOC"
import Content from "./component/Content"

//*컴포넌트들이 '들어가는(나열되는)' 영역
class App extends Component{

  //** 컴포넌트가 실행될때, render 보다 먼저 '초기화'하기 위해 선언 
  constructor(props){ 
    super(props); 
    
    //** 이 안에 초기화할 컴포넌트 요소들을 넣는다.
    this.state={
      subject:{title:'WEB', sub:'world wide web !'}
    }
  }

  render(){
    return (
      <div className="App">
         <Subject title={this.state.subject.title} sub={this.state.subject.sub}></Subject>
         <TOC></TOC>
         <Content title="HTML" desc="HTML is HyperText "></Content>
      </div>
    );
  }
}

export default App;
상위 state 값을                              <--  this.state={ ... }
하위 props 값으로 사용할 수 있다.  <--  {this.state.subject.title}

결과는 이전 코드와 똑같지만 props 값은 생성자 내부에 있는 state를 통해서만 가져온다. 외부에서 알 필요가 없는 정보를 철저하게 숨길 수 있다. 

 

2. TOC 분리하기 

상위 state에서 props의 초기값 지정하고                            <-- this.state = { contents[{...},{...},{...} ] }
상위 state를 하위 props를 TOC.js의 변수로 선언하여         <-- data = { this.state.contents }
다른 props 요소로 활용하기                                                <-- var data = this.props.data

1) app.js

import React, {Component} from 'react';
import './App.css';

//분리된 컴포넌트들 import 
import Subject from "./component/Subject"
import TOC from "./component/TOC"
import Content from "./component/Content"

//*컴포넌트들이 '들어가는(나열되는)' 영역
class App extends Component{
  constructor(props){ //컴포넌트가 실행될때, render 보다 먼저 '초기화'하기 위해 선언, 그안에 초기화할 요소들을 넣는다.
    super(props); 
    this.state={
      subject:{title:'WEB', sub:'world wide web !'},
      content:[
        {id:1, title:"HTML", desc:"HTML is HyperText "},
        {id:2, title:"CSS", desc:"Css is for design "},
        {id:3, title:"JS", desc:"javascript is for intrective "}
      ]
    }
  }

  render(){
    return (
      <div className="App">
         <Subject title={this.state.subject.title} sub={this.state.subject.sub}></Subject>
         <TOC data={this.state.content}></TOC>
         <Content title="HTML" desc="HTML is HyperText "></Content>
      </div>
    );
  }
}

export default App;

2) TOC.js

import React, {Component} from 'react';  //<-- Component class를 로딩하기위해 

//컴포넌트(사용자정의 테그)를 만드는 코드영역
class TOC extends Component{
    //class 안에서는 function을 생략할 수 있다.
    render(){
      var lists=[];
      var data = this.props.data;
      var i=0;
      while(i<data.length){
        lists.push(<li ><a href={"/content/"+data[i].id}> {data[i].title}</a></li>);
        i = i+1;
      }
      return(
        <nav>
          <ul>
            {lists}
          </ul>
        </nav>
      );
    }
  }

  export default TOC; // 외부에서 TOC 안에 있는 요소들을 가져다 쓸 수 있도록 해줌 

3) 에러 수정

에러 | Each child in a list should have a unique "key" prop.   <-- 리액트가 필요해서 요청하는 정보 

li 에 key={data[i].id} 요소 추가

while(i<data.length){
  lists.push(<li key={data[i].id}><a href={"/content/"+data[i].id}> {data[i].title}</a></li>);
  i = i+1;
 }

 

댓글