Web/React & Next.js

만든 프로젝트 최적화하기

코딩은 내 밥줄 2022. 4. 18. 21:47

1. 자신이 전달 받은 prop가 변경될 때

2. 자신의 state가 바뀔 때

3. 부모 컴포넌트가 리렌더링 될 때

4. forceUpdate 함수가 실행될 때

 

1. React.memo함수: 리렌더링 성능 최적화, 리렌더 방지

export default React.memo(TodoListItem);

2. 함수가 계속 만들어지는 상황 방지 -useReduce, useState의 함수형 업데이트 기능 사용

2-1. useState 사용

 function createBulkTodos(){
  const array =[];
  for(let i =1; i <=25; i++){
    array.push({
      id:i ,
      text: `할 일 ${i}` ,
      checked: false
    });
  }
    return array;
}

 
 const [todos, setTodos] = useState(createBulkTodos);
 
 setTodos(todos => todos.concat(todo));

setTodos를 사용할 때 안에 todos => 추가

2-2. useReduce 사용

function createBulkTodos(){
  const array =[];
  for(let i =1; i <=25; i++){
    array.push({
      id:i ,
      text: `할 일 ${i}` ,
      checked: false
    });
  }
    return array;
}

function todoReducer(todos, action){
  switch (action.type) {
    case 'INSERT': // 새로 추가
     return todos.concat(action.todo);
    case 'REMOVE': // 제거
     return todos.filter(todos => todos.id !== action.id);
    case 'TOGGLE': // 토글
     return  todos.map(todo =>
        todo.id === action.id? { ...todo, checked: !todo.checked } : todo,  
      );
    default:
      return todos;
  }
}


const [todos, dispatch] = useReducer(todoReducer, undefined, createBulkTodos);

dispatch({type:'INSERT', todo});

useReducer 사용 시 두 번째 파라미터에 초기 상태를 넣어야 한다 그리하여 undefined를 두 번째 파라미터에 넣고 세 번째에 초기 상태를 만들어주는 createBulkTodos를 넣었다.

 

3. react-virtualized 사용

react-virtualized: 리스트 컴포넌트에서 스크롤되기 전에 보이지 않는 컴포넌트는 렌더링 되지 않고 크기만 차지하게 한다

터미널에 명령어 yarn add react-virtualized 넣기

import React, { useCallback } from 'react';
import {List} from 'react-virtualized';
import TodoListItem from './TodoListItem';
import './TodoList.scss';

const TodoList = ({ todos, onRemove, onToggle }) =>{
    const rowRenderer =useCallback(
        ({idex, key, style}) => {
            const todo =todos[idex];
        
            return(
                <TodoListItem
                    todo= {todo}
                    key= {key}
                    onRemove= {onRemove}
                    onToggle={onToggle}
                />
            );
        }, 
        [onRemove,onToggle,todos],
    );

    return(
        <List
         className='TodoList'
         width={512}
         height={513}
         rowCount={todos.length}
         rowHeight={57}
         rowRenderer={rowRenderer}
         list={todos}
         style={{outline: 'none'}}
        />
    );
};

export default React.memo(TodoList);
import React from 'react';
import {
    MdCheckBoxOutlineBlank,
    MdCheckBox,
    MdRemoveCircleOutline
} from 'react-icons/md';
import cn from 'classnames';
import './TodoListItem.scss';

const TodoListItem = ({ todo, onRemove, onToggle, style }) => {
    const { id, text, checked } = todo;

    return(
        <div className='react-virtualized' style={style}>
            <div className='TodoListItem' >
                <div className={cn('checkbox',{ checked })}
                 onClick={() => onToggle(id)}
                 >
                    {checked ? <MdCheckBox /> : <MdCheckBoxOutlineBlank />}
                    <div className='text'>{text}</div>
                </div>
                <div className='remove' onClick={()=> onRemove(id)}>
                    <MdRemoveCircleOutline/>
                </div>
            </div>
        </div>
    );
}

export default React.memo(TodoListItem);