FrontEnd/react

[react] State

살찐만두 2022. 12. 28. 13:27
728x90

컴포넌트 내부적으로 사용되는 것들이 state 이다.

리액트라는 시스템이 컴포넌트를 만들고 그 컴포넌트가 좋은 부품이 되기 위해서는

외부의 props에 따라서 컴포넌트를 실제로 구성하는 state가 철저히 분리되어있어야 한다.

사용과 구현의 분리가 확실하게 있는 상태로 양쪽의 편의성을 각자 도모하는 것이 좋은 부품을 만드는 것의 핵심이고, 리액트도 마찬가지이다.

 

 

아래 코드로 state를 공부해보자.

class App extends Component {
  render(){
    return (
      <div className="App">
       <Subject title="WEB" sub="world wide web!!!"></Subject>
       <Subject title="react" sub="for ui"></Subject>
       <TOC></TOC>
       <Content title="html" desc="html is hyperText Markup Language."></Content>
      </div> 
    )
  };
}

App 이라는 컴포넌트 안에 Subject라는 하위 컴포넌트가 있다. 하위 컴포넌트들의 props에 지금 하드코딩이 되어있는 것들을 state로 만들고 props로 전달해보자.

 

일단 먼저

constructor 코드를 추가해준다. 

코드는 render함수 위에 추가한다.

class App extends Component {
  constructor(props){
    super(props);
  }
  render(){
    return (
      <div className="App">
       <Subject title="WEB" sub="world wide web!!!"></Subject>
       <Subject title="react" sub="for ui"></Subject>
       <TOC></TOC>
       <Content title="html" desc="html is hyperText Markup Language."></Content>
      </div> 
    )
  };
}

컴포넌트가 실행될 때 render함수보다 먼저 실행이 되면서 컴포넌트를 초기화를 시켜주고싶은 코드는 constructor안에 넣어준다.

 

class App extends Component {
  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>
       <Subject title="react" sub="for ui"></Subject>
       <TOC></TOC>
       <Content title="html" desc="html is hyperText Markup Language."></Content>
      </div> 
    )
  };
}

이런 코드를 작성을 해보았다.

이 코드는 state에 subject에 넘길 props 데이터를 가지고 있다.

render함수의 Subject 태그에서 props로 가지고 올 수 있다.

 

상위 컴포넌트인 App의 상태를 하위 컴포넌트로 전달하고 싶을 때는 state값을 props의 값으로 전달하는 것이 가능하다는 것을 확인할 수 있다.

 

TOC는 리스트 형식으로 되어있기 때문에 배열로 정보를 넣어주자.

class App extends Component {
  constructor(props){
    super(props);
    this.state = {
      subject:{title:'WEB',sub:'World wide web'},
      contents:[
        {id:1, title: 'HTML', desc:'html is ...'},
        {id:2, title: 'css', desc:'css is ...'},
        {id:3, title: 'javaScript', desc:'js is ...'}
      ]
    }
  }
  render(){
    return (
      <div className="App">
       <Subject title={this.state.subject.title} 
                sub={this.state.subject.sub}></Subject>
       <Subject title="react" sub="for ui"></Subject>
       <TOC data={this.state.contents}></TOC>
       <Content title="html" desc="html is hyperText Markup Language."></Content>
      </div> 
    )
  };
}

TOC파일 또는 컴포넌트에서 

class TOC extends Component {
    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>
      )
    };
  }

받아온 props.data를 반복문을 통해서 {lists}로 간단하게 표현할 수 있다. 

 

그런데 이렇게만 했을 때 콘솔창에 오류가 난다.

각 리스트의 항목들은 props에 key가 필요하다는 것이다.

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

반복문 부분에서 li 태그에 key값을 넣어준다.

저 key는 리액트가 필요해서 달라고 하는거기 때문에 그냥 넣어주면 콘솔 에러는 사라지게 된다.

 

부모인 App은 state라는 내부 정보를 사용했고,

자식한테 전달할 때는 props를 통해서 전달했기 때문에 

사용과 구현이 분리되어 코드를 짜고, 사용할 수 있다는 것을 확인할 수 있다.

 

728x90

'FrontEnd > react' 카테고리의 다른 글

[react] shouldComponentUpdate  (0) 2023.02.02
[react] 이벤트에서 state 변경하기  (3) 2022.12.29
[react] Props 기초  (6) 2022.12.27
[react] 컴포넌트 만들기  (4) 2022.12.27
[react] 리액트 설치  (4) 2022.12.27