2019-06-03 react(3)

state

  • 스테이트는 JS객체로 유저 이벤트를 저장하고 반응하는데 사용한다.
  • 컴포넌트 클래스는 그 자체의 스테이트를 가진다. 스테이트가 바뀔때마다 컴포넌트는 즉시 리렌더링을 한다. 자식요소들에게도 렌더링을 하라고 한다.
class SearchBar extends Component {
    render() {
        return <input onChange={ event => console.log(event.target.value) } />;
    }
}
  • 검색바가 어떤 스테이트가 있고 이것이 변하면 render함수가 다시 실행된다.
  • 스테이트를 사용하기전에 초기화를 해야한다. constructor를 넣어야한다.
class SearchBar extends Component {

    constructor(props) {
        super(props);

        this.state = { term: '' };
    }

    render() {
        return <input onChange={ event => console.log(event.target.value) } />;
    }
}
  • 함수형컴포넌트는 스테이트가 없지만 클래스 컴포넌트는 스테이트는 스테이트를 가진다.
  • 모든 JS객체는 constructor를 가진다. 이것은 첫번째로 실행이 된다.
  • constructor 함수는 변수나 상태값을 초기화할때 사용한다.
  • Component함수를 상속받기때문에 Component함수의 constructor를 가진다. super를 통해 부모메소드를 호출한다.
  • term이라는 정보를 가지고 오려한다. term은 search term이다.
  • constructor안에 있는 this.state는 객체다.
class SearchBar extends Component {

    constructor(props) {
        super(props);

        this.state = { term: '' };
    }

    render() {
        // this.state.term = event.target.value => very bad expression
        return (
            <div>
                <input
                    value={this.state.term}
                    onChange={ event => this.setState({ term: event.target.value }) } />
            </div>
        );
    }
}
  • 스테이트는 인풋에게 현재값이 무엇인지를 가르쳐줘야한다.
  • this.state.term에 의해 값을 제공받는 인풋을 제어컴포넌트라고한다. 화면의 인풋을 제어폼 요소라고 표현할 수 있다. 제어컴포넌트는 스테이트에 의해 값이 세팅된다.
  • index.js에서 SearchBar객체가 인스턴스화를 할때, SearchBar.js에서 constructor가 가장먼저 실행되면서 초기화가 진행이 된다. 이때 this.state의 term은 빈문자열이다. 인풋요소에서 아무것도 안가지고 있다가, 입력을 할때마다 this.setState를 이용해서 this.state.term이 업데이트된다.
  • 클래스 컴포넌트는 스테이트를 관리해야될때 쓰고, 함수형 컴포넌트는 어떤 정보와 JSX로 분리될 때 사용한다.

  • 리액트는 하향 데이터 플로우를 지향한다? 모든 부모 컴포넌트는 데이터를 가져올 권리를 가져야 한다.
  • 데이터가 변하면 스테이트를 쓰기좋다.
  • YoutubeAPI를 활용할때 유저가 새 검색어를 입력할때마다, 새검색 프로세스를 통해 스테이트의 검색결과를 보여줄 필요가 있다.
class App extends Component {
    constructor(props) {
        super(props);

        this.state = { videos: [] };

        YTSearch({key: API_KEY, term: 'surfboards'}, (videos) => {
            this.setState({ videos }); // key, variable 이름이 같으면 동작을 한다.
            //ES5 : this.setState({videos: videos})
        });
    }

    render() {
        return <div>
            <SearchBar/>
            <VideoList videos={this.state.videos} />
        </div>
    }
}
  • App에서 비디오리스트로 전달하는 데이터는 videos프로퍼티를 통하여 참조한다. 참조된 요소는 컴포넌트의 props요소로 전달이 된다.
  • 클래스기반 컴포넌트의 props는 this.props를 정이ㅡ해서 사용할 수 있다.

오늘의 느낀점

  • 리액트가 JS기반이라 constructor를 통해 초기화를 하고, 상속에서 super를 통해 부모메소드를 호출하는게 어색하다고 하지만, java를 했기때문에 자바에서 사용했던 생성자와 상속, 부모클래스를 호출하고 객체가 초기화될때 생성자부터 실행이 되고 초기화가 되는 과정이 익숙했다.
  • 컴포넌트에서 상태값을 관리를 하라고 하는데, 이 이야기도 자바 스프링을 하면서 객체의 상태값을 관리하는것에 대해서 계속 신경을 써왔던 부분이다. 어쩌면 나에게 늘 당연하다고 생각했던 부분이 JS에서는 불과 얼마전까지 당연하지 않았고 이 개념이 신박한거 같은데, 자바를 해서 스테이트 대해서는 큰 어려움이 없었다 :)
Written on June 3, 2019