Component 추출하기

    function Comment(props) {
    return (
        <div className = "Comment">
            <div className = "UserInfo">
                <img className = "Avatar"
                    src = {props.author.avatarUrl}
                    alt = {props.author.name}
                    />
                    <div className = "UserInfo-name">
                        {props.author.name}
                    </div>
            </div>
            <div className = "Comment-text">
                {props.text}
            </div>
            <div className = "Comment-date">
                {formatDate(props.date)}
            </div>
        </div>
    );
}

위 코드는 작성자(Avatar), 글(Comment), 날짜(Date)를 prop으로 받는다. 하지만 위 코드는 컴포넌트들이 다 짬뽕되어있기 때문에 좋은 코드라고 할 수 없다. 좋은코드가 되려면 컴포넌트를 최대한 잘게 쪼개야하고, 그 컴포넌트들의 재사용성을 높여야 한다.

    function Avatar (props) {
    return (
        <img className = "Avatar"
        src = {props.author.avatarUrl}
        alt = {props.author.name}
        />
    );
}

쪼개진 Avatar Component

    function UserInfo(props) {
  return (
    <div className="UserInfo">
      <Avatar user={props.user} />
      <div className="UserInfo-name">
        {props.user.name}
      </div>
    </div>
  );
}

UserInfo Component

    function Comment(props) {
  return (
    <div className="Comment">
      <UserInfo user={props.author} />
      <div className="Comment-text">
        {props.text}
      </div>
      <div className="Comment-date">
        {formatDate(props.date)}
      </div>
    </div>
  );
}

UserInfo, Avatar Component가 쪼개져서 간략해진 Comment Component

Props에 관하여

    function sum (a, b) {
        return a + b;
    }

위의 함수는 받아온 props 값을 바꾸지 않은 순수함수이다. 그리고 같은 입력값에 대한 항상 같은 결과를 출력해냅니다.

    function foo (account, amount) {
        account.total -= amount;
    }

다음과같이 props가 변하는 함수를 비순수 함수라고 합니다.

react는 props의 측면에서 봤을때 순수함수처럼 동작해야한다.

그렇다면 props가 고정된 상태에서 react는 어떻게 동적으로 움직일까? state가 그 답이 될 수 있다.

State

  • state는 props와 비슷하다.

  • 하지만 props와는 다르게 private한 특성을 가지고 있다.

  • Component에 의해 완전히 통제된다.

    class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);

위 코드를 살펴보면

  • props를 state에 넘겨주는 과정이 있다.

  • 기존 render에 props가 들어가던 자리에 이젠 state가 들어간다.

state를 정의 하는법

classfields문법을 사용한다.

    class Counter extends Component {
        constructor (props) {
            super(props);
            this.state = {
                number : 0
            }
        }
    }

위코드의 super(props);의 이유는 Component를 상속했기 때문에 기존에 있던 props를 미리 실행하고 state를 설정하기 위함이다.

동적 인자인 state의 값을 바꾸기 위해선 this.setState를 무조건 거쳐야한다.

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

위의 코드처럼 state가 선언되었다고 할 때 이를 바꿔주기 위해선 this.setState({ number : 1 })을 해주면 된다.

그러나 객체안의 객체

    state = {
        number : 0,
        foo : {
            bar : 0,
            foobar : 1
        }
    }

라면 this.setState({foobar : 2})foobar을 2로 바꿀 수는 없다. 따라서 immutable.js 또는 immer.js를 사용하거나 foo 객체 안에 ...this.state.foo라고 this를 연결시켜주어야 한다.

state의 비구조화 할당

    const { number } = this.state;
    this.setState({
        number: number + 1
    });

이런식으로 하면 state에 함수할당이 더 쉽게 가능하다.

이벤트 설정

react 이벤트 설정시 주의사항

  • 이벤트의 이름은 무조건 camelCase로 해주어야한다.(ex onClick)

  • 이벤트에 전달해주는 값은 함수여야 한다. (만든 메소드가 아닌 함수여야 한다는 것)

    <button onClick={this.handleIncrease}>+</button> // 옳은 방식

    <button onClick = {this.handleIncrease()}>+</button> // 틀린 방식 랜더링할때마다 이 함수가 호출되서 무한반복에 빠져버림.