TIL // 2020.12.30

김지민·2020년 12월 30일
0

TIL

목록 보기
14/28

Props와 State가 너무 헷갈려서 복습

1. props

  • 부모 컴포넌트가 자식에게 주는 값

1)Props로 데이터 전달하기

App.js(부모) -> MyName.js(자식) 값 전달 예시

App.js

import React, { Component } from 'react';
import MyName from './components/MyName.js';

class App extends Component {
  render() {
    return (
      <MyName name = "리액트" /> // MyName에 name value값 전달(Props)
    );
  }
}

export default App;

MyName.js

import React, { Component } from 'react';

Class MyName extends Component {
  render() {
    return (
      <div>
        Hi. My Name is <this.props.name> // props로 부모(App.js)에서 데이터 받아옴(name의 value값)
      </div>
    );
  }
}

export default MyName;

2) Props default 값 설정

  • 데이터 전달받지 못했을 때에 디폴트값을 설정해주는 방법
static defaultProps = {
  name : " defaultName "
}

3) 함수형 component에서 props 데이터 전달받기

  • 단순히 데이터를 전달받아서 렌더링만 하는 경우엔 함수형을 사용하는 것이 편함
// 클래스형을 함수형으로 대체
const MyName = ({name}) => {
  return (
  <div>
    Hi. My Name is {name}
  </div>

2. State

  • 컴포넌트 내부에서 선언하며 내부에서 값 변경 가능.
  • 동적인 값을 다루는 방법.
  • Props가 읽기 전용이라면 state는 값의 변경이 가능하다는 것이 특징.
import React, { Component } from 'react';

//1. state 정의
Class Counter extends Component {
  state = {
  number = 0
}

//2. 메소드 작성
handleIncrease = () => {
//3. setState
  this.setState ({
  number : this.state.number + 1
  });
}

handleDecrease = () => {
  this.setState({
    number : this.state.number - 1
    });
  }

//4. 이벤트 설정
render() {
  return (
    <div>
      <h1>카운터</h1>
      <div> 값 : {this.state.number} </div>
      <button onClick = {this.handleIncrease}+</button>
      <button onClick = {this.handleDecrease}-</button>
    </div>

1) state 정의

Class Counter extends Component {
  state = {
  number = 0
}
  • state의 기본값을 정의함.
  • 정의할 때에는 class field 문법 사용
  • class field 문법을 사용하 않으면 constructor함수 작성해서 지정해야함. 피곤

2) 메소드 작성

handleIncrease = () => {
//3. setState
  this.setState ({
  number : this.state.number + 1
  });
}

handleDecrease = () => {
  this.setState({
    number : this.state.number - 1
    });
  }
  • 컴포넌트 내부 메소드 작성
  • this 사용해야 하는 것 기억하기
  • 화살표 함수를 사용하지 않고 작성할 수도 있지만, 화살표 함수를 사용하지 않는 경우엔 각 메소드의 this가 클릭이벤트로 넘어가는 과정에서 연결이 끊겨 undefined로 뜸.
  • 화살표 함수를 사용하지 않을 경우 constructor에서 this를 바인딩해주어야 함.
//바인딩 예시
constructor(props) {
  super(props);
  this.handleIncrease = this.handleIncrease.bind(this);
  this.handleDecrease = this.handleDecrease.bind(this);
}

3. setState

  • state에 있는 값을 바꾸기 위해서는 this.setState를 무조건 거쳐야 함.
  • 리액트는 이 함수가 호출되면 컴포넌트가 리렌더링됨.
  • 메소드 내부에 this.setState를 넣어서 state를 변경하게 만들고 해당 메소드를 호출해 state값을 변경하는 것임.
  • setState는 객체로 전달되는 값만 업데이트를 해준다.
  • 예시에서는 state에 number 하나밖에 없지만 값이 여러 개인 경우 해당하는 값만 변경해줌.
//예시
state = {
  number : 0,
  foo : 'bar'
}
//state값이 두 개인 경우 this.setState({ number : 1}); 을 해주면 아래같이 변경됨

state = {
  number : 1,
  foo : 'bar'
}

3-1. setState

  • 깊은 참조 불가
  • state 객체 내부의 객체에는 접근 불가
  • 첫번째 객체 값만 변경 가능
  • 객체 내부의 객체값에 별도로 접근시 첫번째 객체 자체가 바뀜.
//예시
state = {
  number : 0,
  foo : {
    bar : 0,
    foobar : 1
  }
}
// 이렇게 객체 내 객체가 있는 경우
this.setState({
  foo: {
    foobar : 2
  }
})
//위처럼 한다고 해서 foobar만 바뀌지 않는다.
//그냥 foo 객체 자체가 바뀌어버림
{
  number : 0,
  foo : {
    foobar : 2
  }
}

그래서 state 객체 내부 객체에 접근하기 위해서는 전개연산자를 사용해야함.

this.setState ({
  number : 0,
  foo : {
    ...this.state.foo,
    foobar : 2
  }
});

4. 이벤트 설정

  • html에서의 이벤트 할당과 다름.
//html 방식
<button onclick = "alert('hello');">Click btn</button>
  • html에서는 이벤트 발생시 실행할 js를 문자열 형태로 넣어주는데 jsx는 다름.
<button onClick={this.handleIncrease}>+</button>
  • 주의해야할 점!!
    • 이벤트 이름을 설정할 때 camelCase로 사용. ex) onclick = onClick, onmousedown = onMouseDown
    • 이벤트에 전달해주는 값은 함수.
    onClick = {this.handleIncrease()}
    이런 식으로 호출하면 렌더링할때마다 함수가 호출됨. 그러면
    렌더링 - 함수호출 - setState - 렌더링 - 호출 - 루프
    이렇게 루프에러가 발생함.
profile
wishing is not enough, we must do.

0개의 댓글