리액트의 Props와 State

01 리액트의 핵심

데이터가 바뀌면 화면(을 구성하는 컴포넌트)을 재랜더링 함
이를위해 리액트에는 Props와 State를 사용하여 변경되는 데이터를 체크한다.


02 state와 props의 차이

Props와 State는 비슷하지만 활용목적에 있어 차이가 있다.

state는 컴포넌트에 데이터 저장
props는 컴포넌트간 데이터를 전달


03 생성자(constructor)를 활용한 Value 속성 값 넘기기

  <script type="text/babel">

    class C extends React.Component {
      render(){
        const { text } = this.props
        return(
          <span>Hello World { text }</span>
        )
      }
    }

    class B extends React.Component {
      render(){
        const { value } = this.props //js영역
        return( //jsx영역

          <div className="c_Component"> 
            <C text={value} />
          </div>
        )
      }
    }

    class A extends React.Component {
      render(){
        const { name } = this.props
        return(
          <div>
            <B value={name}/>
          </div>
        )
      }
    }


    class App extends React.Component {
      render(){
        return(
          <div>
            <A name={"heidi"} />
          </div>
        )
      }
    }

    ReactDOM.render(<App />, document.querySelector("#root"));
  </script>

자식 컴포넌트는 value를 통해 부모 컴포넌트에 값을 넘길 수 있음
여기서의 value는 input 속성의 value를 의미하는 것이 아닌, 리액트에서 전달하는 props속성의 이름을 말한다.
ㄴ부모 컴포넌트의 value는 html
ㄴ자식 컴포넌트의 value는 속성 값


04 Class의 생성자(constructor)와 props

부모 컴포넌트에 constructor(props){supet(props)} 를 주면 자식 컴포넌트의 속성 값을 가져올 수 있다.
(최근에는 생략 가능해졌다)

참고 : input type="text" 와 Input value={1} 의 표현식 차이

  1. ""와 {}
  2. jsx 문법과 겹치지 않게 하기 위해 차이를 둔 것임
  3. 컴포넌트 여부에 따라 다름 ( 컴포넌트에서는 변수를 담는 Props 값이기 때문 )
  4. 속성값을 읽는 것이 바로 props인 것이다.
  5. 단점으로는 부모 컴포넌트가 중첩될수록 props 전달하는 과정이 번거로워져 이를 개선하기 위해 Redux가 나옴 (((((나중에 배운다 큰일이다 어렵다던데))))))

참고 : JSX 문법으로 인해 class 속성을 줄 때 className으로 주어야 한다.

브라우저에서는 class로 인식하기 때문이다.

props는 부모로부터 자식에게 속성을 전달하는 방식이다.

넘기는 속성값의 이름은 value가 아닌 다른 것으로도 전달이 가능하다.
render 부분의 js영역의 {}객체와 return의 jsx영역의 {}변수 기호를 구분하는 것이 중요하다.


05 State(상태)

state 기본

  • 리액트에서 사용하는 변수로 이해하면 쉽다.
  • 리액트는 모든 변수를 객체에 담아 사용하며 constructor 생략이 가능하다.
  • 단, 변수명은 state로만 사용해야 한다. 리액트가 state로 고정된 변수를 통해 변경되는 값을 체크하기 때문이다.
    ㄴ 반드시 state로만 사용해야하며, state를 바꾸면 작동이 안된다.
 <script type="text/babel">

    class Login extends React.Component {
      // constructor(props){
      //   super(props)
      //   this.state = {}
      // }

      state = {
        isLogin : false
      }
      // setState({
      //   ...state,
      //   name : 'heidi2'
      // })

      

      render(){
        const obj = {
          ...this.stste,
          isLogin : !this.state.isLogin
        }
        return(
          <button onClick={ () => {this.setState(obj)} }>
            {this.state.isLogin ? '로그아웃' : '로그인' }
          </button>
        )
      }
    }
    
    class App extends React.Component {
      render(){
        return(
          <div>
            <Login />
          </div>
        )
      }
    }

    ReactDOM.render(<App />, document.querySelector("#root"));
  </script>

참고 render()

render()는 컴포넌트가 실행되었을 때 실행되는 함수다. 랜더함수 안에 함수를 넣어두면 계속 실행되기 때문에 state는 가급적 constructor 안에 넣어둔다.

참고 리액트에서 데이터 변경을 체크하는 원리

      {} === {} //false

      state.name = 'heidi'
      const a = state
      state.name = 'heidi2'
      a === state // true

데이터 타입이 객체일때 내용이 바뀌면 변경사실을 체크할 수 없다.
그래서 객체의 내용을 바꿀 때 ...연산자와 this.setState()를 사용한다.
setState는 state변수를 바꿔주는 함수이다.
즉, 리액트는 상태의 값을 바꿔 끼워주는 과정이 필요하다.

06 이벤트로 setState 구현

  <script type="text/babel">

    class Counter extends React.Component {
      state = {
        number : 0,
      }

      increase = (index) => {
        const increase = {
          ...this.state,
          number : this.state.number +index
        }

        this.setState(increase)
      }

      decrease = (index) => {
        const decrease = {
          ...this.state,
          number : this.state.number -index
        }
        this.setState(decrease)
      }

      render(){
 

        return(
          <div>
            <h3>{this.state.number}</h3>
            <button onClick={ ()=> {this.increase(2)} }>+</button>
            <button onClick={ ()=> {this.decrease(2)} }>-</button>
          </div>
        )
      }
    }
    
    class App extends React.Component {
      render(){
        return(
          <div>
            <Counter />
          </div>
        )
      }
    }

    ReactDOM.render(<App />, document.querySelector("#root"));
  </script>

이벤트로 setState 구현시 주의사항

1) 일반 Element를 통해 이벤트를 구현하는 경우, 예를들어 onClick="" 이벤트를 사용하는 경우 "" 내부는 js영역이다. 그러므로 리액트에서는 "" 대신 {}로 감싸주어야한다.

2) onClick처럼 cammel형식으로 사용해야한다. js영역은 관계가 없지만 리액트에서는 작동되지 않아 디버깅시 큰 어려움이 생기기도 한다.

3) onClick 함수를 미리 선언하지 않고 render 안에 두면 클릭하지 않아도 실행된다. 미리 선언하거나, 익명함수 형식으로 작성하도록 하면 문제가 해결된다.

4) 3)의 익명함수 안에 setState()를 사용해주면 값이 변경함에 따라 화면이 바뀐다!!

5) 리액트의 최대 단점 ( 리액트 내 조건부 연산자 사용 규칙 )
ㄴ리액트 내에서는 조건문을 삼항연산자로 사용해야한다.

좋은 웹페이지 즐겨찾기