올해 초 캐나다에서 코딩 공부한지 정말 얼마 안 됬을 때.... 백엔드 친구와 주식 관련 앱을 만들어보려고 했던 적이 있는데 주식 데이터가 실시간으로 너무 많다보니 렌더링이 느리고 성능도 매우 좋지 않았고 최적화를 잘 못하던 시절이라.. 그 시절 내 자신이 정말정말 답답했었다... 😅
아무튼 그때 너무 구현해보고 싶었는데 못 했던 부분이
주식 데이터를 보여줄 때 일단 유저에게 짠 하고 처음 보여지는 부분만 먼저 렌더링하고, 유저가 스크롤하거나 zoom하면 그때 필요한 정보를 가져와서 렌더링하는 기능이었다. 비슷한 로직의 라이브러리를 보니 감회가 새롭다 🤩
이번에는 스크롤 하면서 렌더링 되게 만들어 줄 예정이다
리스트 아이템의 크기를 먼저 재야하는데, 이 때는 두번째 요소부터 해야 테두리가 합쳐진 크기가 나온다.
react-virtualized 를 사용하면
import TodoListItem from "./TodoListItem"
import { List } from 'react-virtualized'
import '../styles/TodoList.scss'
import React, { useCallback } from "react"
const TodoList = ({todos, onRemove, onToggle}) => {
const rowRenderer = useCallback(
// 인덱스, 키, 스타일을 파라미터로 받아옴
({index, key, style}) => {
const todo = todos[index];
return (
<TodoListItem
todo = {todo}
key= {key} //key
onRemove={onRemove}
onToggle={onToggle}
style={style}
/>
)
},[todos, onRemove, onToggle])
return (
<List
className="TodoList"
width={485}
height={513} //전체 높이
rowCount={todos.length} //항목 개수
rowRenderer={rowRenderer}
list = {todos}
style={{ outline: 'none' }} //리스트 자동 적용 스타일 제거
/>
)
}
export default React.memo(TodoList);
List를 import 하고 렌더링 할 함수를 정의해준 다음 props로 전달해주면 된다.
여기까지만 하면 size 때문에 에러가 뜨니 TodoListItem 도 가서 바로 수정해줘야 한다.
import '../styles/TodoListItem.scss'
import cn from 'classnames'
import React from 'react'
import { MdCheckBoxOutlineBlank, MdCheckBox, MdRemoveCircleOutline } from 'react-icons/md'
const TodoListItem = ({todo, onRemove, onToggle, style}) => {
const { id, text, checked } = todo
return (
<div className='TodoListItem-virtualized' style={style}>
<div className="TodoListItem">
<div className= {cn('checkbox', {checked})} onClick={() => onToggle(id)}>
{/* //checkbox 클래스인데 checked 일 경우 동적으로 추가 */}
{!checked? <MdCheckBoxOutlineBlank /> : <MdCheckBox />}
<div className='text'>{text}</div>
</div>
<div className='remove' onClick={() => onRemove(id)}>
<MdRemoveCircleOutline />
</div>
</div>
</div>
)
}
export default React.memo(TodoListItem);
새로 받아온 style props를 추가해주고
리스트 아이템들 사이에 border을 넣어주고 짝수번째에는 배경을 다르게 나타나게 하기 위해 리스트 아이템 전체를 감싸는 div 태그를 만들어준다. (className="TodoListItem")
.TodoListItem-virtualized {
& + & {
//엘리먼트 사이
border-top: 1px solid #dee2e6;
}
&:nth-child(even) {
background: #f8f9fa;
}
}
border과 배경을 각각 넣어주면 끝!
'Computer Programming > [리액트를 다루는 기술]' 카테고리의 다른 글
[리액트를 다루는 기술] 13. 리액트 라우터 (URL /:, 쿼리스트링, 라우트 중첩, useNavigate, Navigate) (0) | 2023.06.20 |
---|---|
React immer 라이브러리로 불변성 유지하기 (0) | 2023.06.20 |
[리액트를 다루는 기술] 11. 컴포넌트 성능 최적화 (1) | 2023.06.19 |
[리액트를 다루는 기술] 10. Todo List 만들기 (2) | 2023.06.17 |
[리액트를 다루는 기술] 9. 컴포넌트 스타일링 (0) | 2023.06.16 |