티스토리 뷰

// class 일 때

state가 바뀌지 않아도 setState를 호출하면 계속 render가 실행 됨

확인 방법은 개발자도구에서 설정버튼 누르고 Highlight updates when components render. 체크

+

불이 들어온다고 항상 렌더가 되고 있는 것은 아님 콘솔을 찍어보는 것이 정확

 

그래서 shouldComponentUpdate를 써줌

값이 바뀌었을 때만 렌더가 실행되도록

import React, { Component } from 'react';

class RenderTest extends Component {
  state = {
    counter: 0
  }

  shouldComponentUpdate(nextProps, nextState, nextContent){
    if (this.state.counter !== nextState.counter) {
      return true;
    } else {
      return false;
    }
  }

  onClick= () => {
    this.setState(
      {}
    );
  }

  render() {
    return (
      <div>
        <button onClick={this.onClick}>클릭</button>
      </div>
    )
  }
}

export default RenderTest;

Context

A -> B -> C -> D -> E -> F -> G 이렇게 컴포넌트가 있을 때

A가 G에게 값을 넘겨주고 싶을 때, 중간에 있는 컴포넌트들에게는 필요없는 props를 넣어서 값을 전달하면 불필요한 렌더링이 발생할 수 있어 G에게 바로 전달해줄 때 사용 > context의 진화형이 redux


PureComponent

알아서 shouldComponentUpdate 기능을 구현해놓은 컴포넌트

import React, { PureComponent } from 'react';

class RenderTest extends PureComponent {
  state = {
    counter: 0
  }

  shouldComponentUpdate(nextProps, nextState, nextContent){
    if (this.state.counter !== nextState.counter) {
      return true;
    } else {
      return false;
    }
  }

  onClick= () => {
    this.setState(
      {}
    );
  }

  render() {
    return (
      <div>
        <button onClick={this.onClick}>클릭</button>
      </div>
    )
  }
}

export default RenderTest;

 

하지만 객체나 배열이 있으면 판단하기 어려워함

> 배열에 push를 써서 수정하면 알아차리지 못함, 그래서 새로운 배열을 만들어서 사용하는 것임

이것은 컴포넌트나 퓨어컴포넌트나 공통 원칙

setTries((prevTries) =>
        [...prevTries, { try: value, result: '홈런!' }] // [...이전배열, 추가값]
      );

 

그리고 배열안에 객체안에 배열 이런식으로 자료구조를 복잡하게 하지 말것, 실수할 수 있음

 

컴포넌트가 복잡해지면 퓨어컴포넌트가 안될 때도 있음

 

꼭 PureComponent만 쓰는건 아니고, 원하는 것만 설정할 때가 있어서 shouldComponentUpdate를 함께 씀

+

제일 마지막 자식은 PureComponent를 사용해도 됨, 보통 데이터를 담고 있다기 보다는 화면역할을 하는 경우가 많아서..


// hooks일 때

memo 사용

컴포넌트를 메모로 감싸면 됨

import React, { memo } from 'react';

const Try = memo( ({ tryInfo }) => {
  return (
    <li>
      <div>{tryInfo.try}</div>
      <div>{tryInfo.result}</div>
    </li>
  )
});

export default Try;

툴이 자꾸 렌더를 하고 있다고 보여주는게 틀릴 때도 있음

콘솔을 찍어보는 것이 정확

 

자식들이 모두 퓨어 컴포넌트나 메모라면 부모에도 적용할 수 있음


ref를 쓰는 다른 방법 

createRef

class와 hooks가 current를 사용하는 비슷한 형태가 됨!

import React, { Component, createRef } from 'react'; // createRef import해주기
import Try from './Try-class';



...생략...



class NumberBaseball extends Component {
  state = {
    value: '',
    result: '',
    answer: getNumbers(),
    tries: [],
  };

  onSubmitForm = (e) => {
    e.preventDefault();
    if (this.state.value === this.state.answer.join('')) {
      this.setState((prevState) => {
        return {
          result: '홈런!',
          tries: [...prevState.tries, { try: this.state.value, result: '홈런!' }],
        }
      });
      alert('게임을 다시 시작합니다!');
      this.setState({
        value: '',
        answer: getNumbers(),
        tries: [],
      });
      this.inputRef.current.focus(); // current 랑 같이 써줌
    } 
    ...생략....
    
    
    
  inputRef = createRef(); // createRef 적용

  render() {
    const { result, value, tries } = this.state;
    return ( // 태그안에 ref추가
      <>
        <h1>{result}</h1>
        <form onSubmit={this.onSubmitForm}>
          <input ref={this.inputRef} maxLength={4} value={value} onChange={this.onChangeInput} />
        </form>
        <div>시도: {tries.length}</div>
        <ul>
          {tries.map((v, i) => {
            return (
              <Try key={`${i + 1}차 시도:`} tryInfo={v} />
            ); // props로 전달
          })}
        </ul>
      </>
    );
  }
}

export default NumberBaseball;

 

지난번에 썼던 방식은 미세하게 조정을 할 수 있음

함수라 더 자유도가 있음

 

간단하게 하고 싶으면 createRef

복잡하게 설정할거면 (c) => {      }

728x90
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
글 보관함