즐코

props와 state 본문

React

props와 state

YJLEE_KR 2022. 4. 13. 17:22

 

데이터가 바뀌면 화면(컴포넌트)이 바뀐다.

데이터가 추가/삭제/수정된 거를 알아채서 그 컴포넌트만을 바꿔준다.

 

원래는 props를 쓰려면 아래처럼 constructor로 props라는 인자를 React객체로부터 받아와야하는데 생략이 가능해서 엥간하면 생략한다. 

props는 부모 (상위) 엘리먼트가 물려준 속성값이라고 생각하면 된다. 나중에 html태그의 속성값과 헷갈리면 안된다.

Input에서 this.props를 출력해보면 아래와 같이 객체가 전달된다.

 

App이라는 컴포넌트가  Input 하위 컴포넌트에 객체형태의 데이터를 전달해준거고, 

Input 컴포넌트가 그걸 받아서 value로 써먹은 거다 

 <div id="root"></div>
 
 <script type="text/babel">
 
   class Input extends React.Component {
      // constructor(props) {
      //   super(props)
      // }
      render() {
        return (
          <input type="text" value={this.props.name} />
        )
      }
    }

   class App extends React.Component {
      render() {
        return (
          <div>
            <Input value={1} name={'ingoo'} age={'33'} />
          </div>
        )
      }
    }
    
ReactDOM.render(<App/>, document.querySelector('#root'))

</script>

 

state : 내 컴포넌트 안에 저장된 데이터를 담은 객체

한 컴포넌트 클래스나 함수 내에서 하나밖에 쓰지 못한다. state라고만 명시해야한다. 다른 변수명은 안됨

 

- 리액트에서의 이벤트

 

1- camelCase 사용 

2- 문자열이 아닌 함수/객체형태로 이벤트핸들러 전달

 

HTML : <button onclick = 'changeLog'>login</button>

JSX : <button onClick = {changeLog}>login</button>

 

3. this.setState( )

평소 자바스크립트에선 객체의 속성값을 바꿀 때 state.isLogin = true 이런식으로 바꾸곤 했다. 

 

하지만, 리액트에선 setState()메소드를 써야한다.

원래 state는 가만히 두고, 다른 객체를 하나 만들어서(obj) 깊은 복사를 하고(...this.state)

속성값을 바꾼 후(isLogin : !this.state.isLogin)에

그 다른 객체를 setState()의 인자로 넣어줬다.

 

이때 그냥 <button onClick = {this.setState(obj)}> 하면 클릭하기도 전에 실행되어 오류가 발생한다.

 

따라서, 익명함수에 담아서 함수가 호출되는걸 막아준다. 

<button onClick = { ( )=>{ this.setState(obj) } }>

 

4. react에선 if문을 쓸 수 없다. 대신 삼항연산자를 쓴다.

{ this.state.isLogin ? 'logout' : 'login'}

 

<div id="root"></div>
  <script type="text/babel">
  
    class Login extends React.Component {
      state = {
        isLogin: false
      }
      render() {
        const obj = {
          ...this.state,
          isLogin: !this.state.isLogin,
        }
        return (
          // 바로 실행되지 않게끔 익명함수로 선언 해준다. 
          <button onClick={() => { this.setState(obj) }}>
            {this.state.isLogin ? 'logout' : 'login'}
          </button>
        )
      }
    }

    class App extends React.Component {
      render() {
        return (
          <div><Login /></div>
        )
      }
    }

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

 

근데 컴포넌트의 render함수 안에 많은 코드가 들어가는 건 좋지않다.

아래와 같이 다 밖으로 빼주는 게 좋다. 

 

  class Login extends React.Component {

      state = {
        isLogin: false
      }

      loginStatus = () => {
        const loginLogout = {
          ...this.state,
          isLogin: !this.state.isLogin,
        }

        this.setState(loginLogout)
      }

      render() {

        return (
          <button onClick={this.loginStatus}>
            {this.state.isLogin ? 'logout' : 'login'}
          </button>
        )
      }
    }

 

counter 만들어보기

 

<div id="root"></div>
  <script type="text/babel">

    class Counter extends React.Component {

      state = {
        number: 0
      }

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

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

      render() {
        return (
          <div>
            <h3>{this.state.number}</h3>
            <button onClick={() => { this.plus(2) }}>+</button>
            <button onClick={() => { this.minus(2) }}>-</button>
          </div>
        )
      }
    }

    class App extends React.Component {
      render() {
        return (
          <div>
            <Counter />
          </div>
        )
      }
    }

    ReactDOM.render(
      <App />, document.querySelector('#root')
    )

  </script>
Comments