Performance

Jaeseok Han·2023년 11월 10일
0

React Basic

목록 보기
25/30

Performance

Lower State / Push The State Down

컴포넌트가 리렌더링되는 경우

  • 컴포넌트의 상태(state)나 속성(props)이 변경되면, React는 이러한 변경 사항을 반영하기 위해 컴포넌트를 리렌더링한다.
  • 부모 요소가 리렌더링될 때(컴포넌트의 상태나 속성이 변경되지 않더라도)
  • 하위 상태(lower state)

index.jsx

import { useState } from 'react';
import { data } from '../../../../data';
import List from './List';
const LowerState = () => {
  const [people, setPeople] = useState(data);
  const [count, setCount] = useState(0);

  return (
    <section>
      <button
        className='btn'
        onClick={() => setCount(count + 1)}
        style={{ marginBottom: '1rem' }}
      >
        count {count}
      </button>
      <List people={people} />
    </section>
  );
};
export default LowerState;

List.jsx

import Person from './Person';

const List = ({ people }) => {
  return (
    <div>
      {people.map((person) => {
        return <Person key={person.id} {...person} />;
      })}
    </div>
  );
};
export default List;

Person.jsx

import { useEffect } from 'react';

const Person = ({ name }) => {
  console.log('render');
  // useEffect(() => {
  //   console.log('unfortunately does not fix the issue');
  // }, []);
  return (
    <div>
      <h4>{name}</h4>
    </div>
  );
};
export default Person;

위의 경우 최초 렌더링시 'render'가 출력이 된다.
index.jsx에서 클릭이벤트(setCount)로 count의 상태 값이 변하므로 자식 요소인 Person.jsx도 리렌더링 된다.

해결방법

index.jsx

import { useState } from 'react';
import { data } from '../../../../data';
import List from './List';
import Counter from './Counter';
const LowerState = () => {
  const [people, setPeople] = useState(data);

  return (
    <section>
      <Counter/>
      <List people={people} />
    </section>
  );
};
export default LowerState;

Counter.jsx

import React, { useState } from 'react'

const Counter = () => {
  const [count, setCount] = useState(0);

  return (
    <button
        className='btn'
        onClick={() => setCount(count + 1)}
        style={{ marginBottom: '1rem' }}
    >
        count {count}
    </button>
  )
}
export default Counter

따로 상태를 관리하는 컴포넌트를 분리하여 하위 컴포넌트들이 리렌더링되는 것을 방지할 수 있다.

Lower State Challenge

  • 리렌더링 수정
  • 힌트 : addPerson을 수정한다.

index.jsx

import { useState } from 'react';
import { data } from '../../../../data';
import List from './List';
const LowerStateChallenge = () => {
  const [people, setPeople] = useState(data);
  const [name, setName] = useState('');

  const handleSubmit = (e) => {
    e.preventDefault();
    if (!name) {
      alert('Please Provide Name Value');
      return;
    }
    addPerson();
    setName('');
  };
  const addPerson = () => {
    const fakeId = Date.now();
    const newPerson = { id: fakeId, name };
    setPeople([...people, newPerson]);
  };
  return (
    <section>
      <form className='form' onSubmit={handleSubmit}>
        <div className='form-row'>
          <label htmlFor='name' className='form-label'>
            name
          </label>
          <input
            type='text'
            name='name'
            id='name'
            className='form-input'
            value={name}
            onChange={(e) => setName(e.target.value)}
          />
        </div>
        <button className='btn btn-block' type='submit'>
          submit
        </button>
      </form>
      <List people={people} />
    </section>
  );
};
export default LowerStateChallenge;

List.jsx

import Person from './Person';

const List = ({ people }) => {
  return (
    <div>
      {people.map((person) => {
        return <Person key={person.id} {...person} />;
      })}
    </div>
  );
};
export default List;

Person.jsx

const Person = ({ name }) => {
  console.log('re-render')
  return (
    <div>
      <h4>{name}</h4>
    </div>
  );
};
export default Person;

이름 인풋 값과 추가될 경우 리렌더링된다.

0개의 댓글