Day of Nomad

컨테이너 구현하기 Building container 본문

Develop/React

컨테이너 구현하기 Building container

DeveloperYong 2018. 6. 26. 17:52

컨테이너와 컴포넌트의 차이점에 대해 공부해 봤습니다.


booklist를 컴포넌트 대신에 컨테이너로 만들기로 결정했죠.


리액트와 리덕스는 아무런 접점이 없다는거 알고 계시죠?


데이터를 가지고 있는 어플리케이션 스테이트를 위한 리덕스와


실제 컴포넌트를 연결하기 위하여, 독립적인 라이브러리인 리액트-리덕스를 사용해야하는데요.



이를 통해 연결하게 되죠.


컴포넌트와 리덕스를 연결할 때마다 컴포넌트는 컨테이너로 변환되거나


사용을 원하는 방식의 컴포넌트로 변환이 됩니다.



자 그럼 이전에 만들었던 booklist 컴포넌트를 만들었는데요, 그러나 아직


어플리케이션 안에 사용하지 않았지요.


app.js로 넘어가, 어플리케이션 안에서 렌더링이 되도록 해봅시다.



// src/components/app.js

import React from 'react';
import { Component } from 'react';

import BookList from '../containers/book-list';
;
export default class App extends Component {
render() {
return (
<div>
<BookList />
</div>
);
}
}


containers 디렉토리에 있는 booklist 컴포넌트를 불러와 렌더링 시켰습니다.


간단해보이죠? 이  booklist는 app에 렌더링 되었습니다.


이제 booklist가 실제로 리덕스로부터 스테이트를 가져와 컴포넌트로 연결하는 것이 필요합니다.


최종 목표는 이 어플리케이션 스테이트가 books프로퍼티를 가지는 것인데요.


이 책 리스트를 가져와 컴포넌트 안에 보여지도록 만들기를 원합니다.


이제 이를 연결하기 위해 react-redux를 불러옵니다.


// src/containers/book-list.js

import React, { Component } from 'react';
import { connect } from 'react-redux';

class BookList extends Component {

renderList() {
return this.props.books.map((book) => {
return (
<li key={book.title} className="list-group-item">{book.title}</li>
)
});
}

render() {
return (
<ul classNmae="list-group col-sm-4">
{this.renderLikst()}
</ul>
)
}
}



이렇게 상단에 react-redux를 불러오구요.  하나의 프로퍼티를 가져오기 위해, {}를 사용합니다.


이렇게 connect를 싱글 프로퍼티로 작성합니다.(모두 소문자로요).


이제 connect함수를 얻었는데요. 이는 함수입니다. 이를 사용해 보지요.


이제 이 클래스를 기본으로 내보내지 않을 것인데요.(class앞에 export default를 지워줍니다.)


이제 단지 컴포넌트만 상속받는 형태입니다.


그리고 하단에 함수하나를 입력해줍니다.


// src/containers/book-list.js

import React, { Component } from 'react';
import { connect } from 'react-redux';

export default class BookList extends Component {

renderList() {
return this.props.books.map((book) => {
return (
<li key={book.title} className="list-group-item">{book.title}</li>
)
});
}

render() {
console.log(this.props.nomad) // -> 'yong'
return (
<ul classNmae="list-group col-sm-4">
{this.renderLikst()}
</ul>
)
}
}

function mapStateToProps(state) {
// Whaterver is required will show up as props
// inside of BookList

return {
nomad : 'yong'
}
}


이 함수 기능은 함수이름 그대로 입니다.


믿기 힘들겠지만, 이는 정확히 무슨일이 일어나는지 설명이 되죠.


이 함수의 목적은 어플리케이션 스테이트를 요소로 가지는 것인데요.


스테이트는 책 배열과 활성화된 책을 가지고 있죠.


이제 어플리케이션 스테이트를 가져와서 여기서 반환되는 것 무엇이든지.


booklist 안의 props 형태로 보여질 것입니다.


그래서 종종 여기에 오브젝트를 반환하는데요. 이는 subject안에 위치하고,


this.props로 세팅됩니다.


만약 여기에 nomad: 'yong'이 반환되면  콜솔로그에 'yong'이 출력되겠죠.


이 함수는 무척 잘 지어진 이름이죠.


이는 어플리케이션 스테이트를 가져와 무엇이든지 함수로 반환하고,


컨테이너 안에 어떤 것을  props로 보여줄지를 나타내죠.


자 그럼 이제 컨테이너가 리덕스와 리액트를 왜 연결하는지 알아보겠습니다.


이 mapStateToProps 함수를 통해 연결됩니다.



// src/containers/book-list.js

import React, { Component } from 'react';
import { connect } from 'react-redux';

export default class BookList extends Component {

renderList() {
return this.props.books.map((book) => {
return (
<li key={book.title} className="list-group-item">{book.title}</li>
)
});
}

render() {
console.log(this.props.nomad) // -> 'yong'
return (
<ul classNmae="list-group col-sm-4">
{this.renderLikst()}
</ul>
)
}
}

function mapStateToProps(state) {
// Whaterver is required will show up as props
// inside of BookList

return {
books: state.books
}
}

export default connect(mapStateToProps)(BookList);



books 라 불리우는 프로퍼티가 필요한데, 왜냐하면, 이를 this.props.boos로 참조하기 때문이죠.


이것의 값으로 책의 리스트를 가져오길 원합니다.


스테이트가 두 프로퍼티로 이루어진 것을 기억하구요. books와 activeBook 이죠.


books는 책의 배열이구요. 이는 정확히 우리가 필요한 것이죠.



그래서 state.books로 작성합니다. 이는 리덕스와 컨테이너의 컴포넌트와 연결하는 방식이죠.


하나 더 스텝이 있는데, 아래에 우리가 불러왔던  connect 함수를 이용할 필요가 있는데요.


이 connect함수는 이 컴포넌트를 가져오고 mapStateToProps를 가져와,


컨테이너를 반환하는 거죠. 그리고 이는 파일로부터 내보낼 필요가 있죠.


이전에 export를 지웠는데요. 컨테이너 파일을 만들때마다 booklist를 내보내는 것이 아니구요.


이는 사용이 되지 않는 것입니다. 컨테이너를 내보내기 원합니다.


connect로 mapStateToProps를 넣고, 두번째로 booklist를 넣습니다. 두개의 독립적인 호출이죠.



마지막으로 두가지 매우 중요한 것이 남았습니다.


첫번째는 어플리케이션 스테이트가 변할때마다 만약 리모트 서버로 부터 책 리스트를 로딩한다고 가정하면,


이에 대한 시간이 걸리고, 유저가 어떤 것을 클릭하면, 이 책 리스트가 변할거에요.


이 스테이트가 변하면, 컨테이너는 즉시 리렌더링하여 새 책 리스트를 갖겠죠.


이 장점은 어느 곳에든 쓰일겁니다. 어플리케이션 스테이트가 바뀔때마다, 컴포넌트와 컨테이너 booklist는


자동적으로 리렌더링 될거에요.


두번째 중요한 것은 connect를 사용함으로써, 컨테이너를 생성하는데요. 어플리케이션 스테이트가 바뀔 때 마다,


스테이트 함수 안의 객체가 컴포넌트의 props로 할당 될겁니다.(this.props,books)



그러면 이제 컨테이너가 갖춰졌구요. 브라우저로 가서 리프레쉬를 하면, 실제로 동작하는 것을 볼 수있습니다.




Comments