RN state, props

RN에서 props와 state가 뭘까요?

props는 UI편을 했다면 쉽게 알수 있습니다. 속성입니다. state는 뭘까요? 상태입니다.

아직 잘 모르겠죠?

실제로 코드를 사용해 볼까요?

가장 간단한 inputText을 이용한 예제를 보죠.

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  TextInput
} from 'react-native';

class gitbookTest2 extends Component {
  componentWillMount() {
    this.setState({
      inputText: '',
    })
  }

  render() {
    return (
      <View style={styles.container}>
        <TextInput
          style={{height: 40,borderColor: 'gray', borderWidth: 1}}
          onChangeText={(text) => { this.setState({inputText: text}) }}
          value={this.state.inputText}
          />
        <Text>
          {this.state.inputText}
        </Text>
      </View>
    );
  }
}

실행을 해보면 input에 쓴대로 밑에 text에 보이게 됩니다.

여기서 onChangeText는 input의 Text가 바뀔때 실행되는 함수입니다.

한번 확인을 해볼까요?

시뮬레이터에서 command+D 을 클릭하면 Debug JS Remotely 라는 버튼이 있을거에요. 그걸 클릭하면 크롬창에 RN Debbug 창이 생깁니다. option + command + i 버튼을 클릭하여서 개발자 도구를 킨다음 콘솔창을 킵니다.

class 위에 console.log('check')을 추가한후 command+R을 눌러서 재로딩을 해봅시다. 그다음 크롬 디버깅창을 보면 check 가 잘 나왔다면 성공입니다. 전 'check'대신 1로 하였습니다. 저부분에 check가 뜨면 성공입니다. 이제

<TextInput
          style={{height: 40,borderColor: 'gray', borderWidth: 1}}
          onChangeText={(text) => {
            console.log(text)
            this.setState({inputText: text})
          }}
          value={this.state.inputText}
          />

onChangeText함수를 살짝 바꿉니다. 그다음에 실행을 하고 문자를 입력하고 debug창을 확인해봅시다. 값이 바뀔때 마다 실행이 되는것을 확인 할 수 있습니다.

여기서 계속 보이는 this.setState 함수는 무엇일까요?

이건 이 컴포넌트의 state 값을 업데이트해주는 함수입니다.

우리는 setState을 이용하여서 this.state.inputText 값을 계속 바꾸어 주었습니다. 그래서 Text 안의 this.state.inputText가 우리가 입력한 값이 되었던 것이죠.

그렇다면 맨처음에 있던

componentWillMount() {
    this.setState({
      inputText: '',
    })
  }

은 무엇일까요? 이건 component가 실제 render 하기 전에 실행되는 함수 입니다.

여기서 우리는 inputText을 빈 문자열로 바꾸었습니다. 이 부분이 없다면 this.state.inputText가 정의 되지 않았다는 에러가 뜰것입니다.

간단하게 componentWillMount 에서는 render에 사용할 state을 초기화 해주었습니다.

RN에서는 component을 실제로 사용하게 되면

componentWillMount -> render -> componentDidMount 순서대로 함수가 실행되게 됩니다. 즉 실제로 render했던 부분을 수정하고 싶다면 componentDidMount 함수를 사용하여야 합니다. 잘 모르시겠다면 react lifecycle에 대해 검색해 주세요.

그렇다면 우리는 계속 state 을 이용했는데 props는 무엇일까요?

간단하게 얘기하면 state 는 변수 props는 상수 입니다.

응??? props 값이 바뀔수도 있는 거잖아 라고 생각할수 있습니다.

<TextInput
          style={{height: 40,borderColor: 'gray', borderWidth: 1}}
          onChangeText={(text) => {
            console.log(text)
            this.props.text = text;
            this.setState({inputText: text})
          }}
          value={this.state.inputText}
          />
        <Text>
          {this.props.text}
        </Text>

코드를 이렇게 바꾸어서 실행을 해보세요. 그다음 어떻게 되는지 확인을 해주세요.

아마 Text가 안바뀔거 에요.

왜 그럴까요? 정확히 얘기는 하면 props값도 바꿀수 있습니다. 하지만 react에서는 props 값을 관찰하고 있지 않습니다. 즉 props 값이 바뀌여도 새로 view을 업데이트 하지 않는다는 것이지요. react는 setState 함수가 실행될때 그 state 값이 포함된 view을 업데이트 합니다. 이게 react 빠른 이유이고 react가 사용하는 virtual Dom 이라는 기술입니다. (혹시 더 깊이 알고 싶으시다면 react virtual Dom을 검색해 보세요)

만약 props가 state 값을 사용하고 있다면 view가 업데이트 됩니다.

예를 들어볼까요?

class CustomText extends Component {
  render() {
    return (
      <Text>{this.props.text}</Text>
    )
  }
}


class gitbookTest2 extends Component {
  componentWillMount() {
    this.setState({
      inputText: '',
    })
  }

  render() {
    return (
      <View style={styles.container}>
        <TextInput
          style={{height: 40,borderColor: 'gray', borderWidth: 1}}
          onChangeText={(text) => {
            console.log(text)
            this.setState({inputText: text})
          }}
          value={this.state.inputText}
          />
        <CustomText text={this.state.inputText}/>
      </View>
    );
  }
}

코드를 이렇게 바꾸고 실행을 해보세요. 이상하게 CustomText는 props 을 사용하고 있는데 계속 view가 업데이트 됩니다.

여기서 CustomText는 state을 참조하고 있기 때문에 CustomText는 새로 그려지게 되는 것이지요.

즉 계산으로 나오거나 예측가능한 값 => props

사용자의 입력등, 꼭 입력을 받아야 하는 값 => state

입니다. 어렵게 생각하지 말고 입력을 받는 값을 state로 주시고 나머지는 props을 통해서 그 값을 잘 계산, 전달 해 주시면 됩니다.

아직 이해가 덜 되셧다면 이 글을 한번 다시 읽으시고, 다시 따라해보시고 그래도 이해가 안되시면 더 좋은 글을 읽어주세요 ㅠㅠㅠㅠㅠ (제가 글을 잘 못써서 죄송합니다. ㅠㅠ )

results matching ""

    No results matching ""