๋ถ๋ชจ์ปดํฌ๋ํธ์ state๊ฐ ํ๋๋ง ๋ณํด๋ ํ์์ปดํฌ๋ํธ ์ ์ฒด์ ๋ฆฌ๋ ๋๋ง์ด ์ผ์ด๋๊ธฐ ๋๋ฌธ์
์๋ชป ์ฌ์ฉํ๋ฉด ๋ฉ๋ชจ๋ฆฌ๋ญ๋น๊ฐ ํฌ๊ฒ ๋ฐ์ํ๋ฉฐ ์ฑ๋ฅ์ด ๋จ์ด์ง ์ ์๋ค
React app์ ์ฑ๋ฅ ์ต์ ํ๋ฅผ ์ํด ๋ฆฌ๋ ๋๋ง ๋๋ ๋ถ๋ถ์ ์ต์ํํด์ผ ํจ
useMemo(์คํํ ํจ์, [๋ณํํ๋์ง ์ง์ผ๋ณผ ๊ฐ(Dependency)]);
useCallback(์คํํ ํจ์, [๋ณํํ๋์ง ์ง์ผ๋ณผ ๊ฐ(Dependency)])
export default React.memo(์ปดํฌ๋ํธ)
dependency๋ฅผ ๋น์ด
useCallback()
์์ฑ๋ฒ
dependency๋ฅผ ๋น์ฐ์ง ์์ useCallback()
const [userInput, setUserInput] = useState(''); const onChange = useCallback(e => { const { name, value } = e.target; setUserInput({...userInput, [name]: value}); },[userInput])
dependency๋ฅผ ๋น์ด useCallback()
const [userInput, setUserInput] = useState(''); const onChange = useCallback(e => { const { name, value } = e.target; setUserInput((prev) => ({...prev, [name]: value})); },[])
(setterํจ์ ์ฌ์ฉ ์, ์ด์ state๋ฅผ ์ธ์๋ก ๋ฐ์์ ์ฌ์ฉ)
$ yarn add lodash
inputํ๊ทธ์ onChange
ํน์ ์คํฌ๋กค ์ด๋ฒคํธ์ ๊ฐ์ด ์งง์ ์๊ฐ์์ ๋๋ฌด ๋ง์ ํจ์์ ์ฌํธ์ถ์ด ์ผ์ด๋๋ ๊ฒฝ์ฐ ์ฌ์ฉ
lodash์ debounce๋ฅผ ์ฌ์ฉํ๋ฉด, ์ง์ ํ ํจ์์ ๋ง์ง๋ง ํธ์ถ๋ก๋ถํฐ ์ง์ ํ ์๊ฐ๋์ ํจ์์ ์ฌํธ์ถ์ด ์ผ์ด๋์ง ์๋ ๊ฒฝ์ฐ์๋ง ํจ์๊ฐ ์คํ๋๋ค
debounce( ์คํํ ํจ์ , 500 )
$ yarn add react-window
ํ ํ๋ฉด์ ๋๋ฌด ๋ง์ ์ปจํ ์ธ ๊ฐ ์ ๋ก๋๋์ด์ผ ํ ๋ ์ฌ์ฉ
์ง์ ํ ํ๋ฉด์ ํฌ๊ธฐ์์ ๋ค์ด์ค๋ ์์ ์ปจํ ์ธ ๋ง ๋จผ์ ๋ ๋๋ง ๋๋๋ก ํจ
๋์น๋ ๋ฐ์ดํฐ๋ ์คํฌ๋กค์ ์์น์ ๋ฐ๋ผ ํ์ํ ๋ ๋ ๋
โจ์ฌ์ฉ๋ฒ
import React from 'react'
import { userData as users } from '../data/users'
import { FixedSizeList as List } from 'react-window'
function Users() {
return (
<List width={500} height={500} itemSize={50} itemCount={80}>
{({index, style}) =>
<div key={users[index].id} style={style} >
{users[index].name}
</div>
}
</List>
)
}
export default Users
import { FixedSizeList as List } from 'react-window'
๋ก ์ปดํฌ๋ํธ๋ฅผ ๋ถ๋ฌ์ด
์ปดํฌ๋ํธ์ ๋ฐ์ดํฐ๊ฐ ๋ณด์ฌ์ง ์ฐฝ์ ํฌ๊ธฐ๋ฅผ ์ง์ ํ๋ width
, height
๊ฐ ๋ฐ์ดํฐ๊ฐ ์ฐจ์งํ ๋์ดitemSize
, ์์ดํ
์ ๊ฐฏ์ itemCount
๋ฅผ ์ค์
<List width={500} height={500} itemSize={50} itemCount={80}></List>
์ปดํฌ๋ํธ ๋ด์ ํจ์๋ฅผ ๋ฃ๊ณ ํด๋น ํจ์์ ์ธ์๋ก index
์style
๋ฅผ ๊ฐ์ฒด๋ถํดํ ๋น์ผ๋ก ๋ฐ์์ด
ํจ์์์์ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํด ์ปดํฌ๋ํธ๋ฅผ ๊พธ๋ฉฐ์ฃผ๋๋ฐ, map()
์ ์ฌ์ฉํ๋ ๋์ ์ธ์๋ก ๋ฐ์ index
๋ฅผ ํ์ฉํ๋ค
ํจ์ ๋ด ์ต์๋จ ์์์ ์ธ์๋ก ๋ฐ์ style
์ ์ ์ฉ์์ผ์ค
๋ฆฌ์กํธ๋ ์ด๊ธฐ ๋ก๋ฉ๊ณผ์ ์์ ์ ์ฒด ์ปดํฌ๋ํธ๋ฅผ ํ๋ฒ์ ๋ถ๋ฌ์ค๋๋ฐ, ํ์ด์ง ์ ํ์ด ๋น ๋ฅด๋ค๋ ์ฅ์ ์ด ์์ง๋ง ์ด๊ธฐ ๋ก๋ฉ์๊ฐ์ด ์ค๋ ๊ฑธ๋ฆฐ๋ค๋ ๋จ์ ์ด ์์
lazy()๋ ํน์ ์ปดํฌ๋ํธ๊ฐ ๋์ค์ ๋ถ๋ฌ์์ง๋๋ก ๋ถ๋ฆฌ
๊ธฐ์กด ์ปดํฌ๋ํธ import๋ฐฉ์
import UserList from './components/UserList';
function App() {
return (
<UserList />
)
}
lazy ๋ฐฉ์
import { lazy, Suspense } from 'react';
const UserList = lazy(() => import('./components/UserList'))
function App() {
return (
<Suspense fallback={์ปดํฌ๋ํธ}>
<UserList />
<Suspense>
)
}
- ๋ง์ฝ lazy์ปดํฌ๋ํธ๊ฐ ๋ก๋๋๊ธฐ ์ ์ ํด๋น ์ปดํฌ๋ํธ๋ฅผ ๋ถ๋ฌ์์ผ ํ ๋, ๋ก๋๊ฐ ์๋ฃ ๋ ๋ ๊น์ง suspense์ fallback์์ ์ปดํฌ๋ํธ๋ฅผ ๋จผ์ ๋ถ๋ฌ์์ ๋ณด์ฌ์ค๋ค.
(fallback์์ ๋ก๋ฉ์ด๋ฏธ์ง๋ฅผ ๋ณด์ฌ์ฃผ๋ ์ปดํฌ๋ํธ๋ฅผ ๋ถ๋ฌ์ค๋ ๋ฐฉ์์ ์ฌ์ฉํ ์ ์์)
$ yarn add react-lazy-with-preload
ํน์ ํ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ ๋, ์ง์ ํ ์ปดํฌ๋ํธ๋ฅผ ๋ถ๋ฌ์ด
์ปดํฌ๋ํธ.preload()
๋ฅผ ํธ์ถํ์ ๋, ํด๋น ์ปดํฌ๋ํธ๋ฅผ ๋ถ๋ฌ์จ๋ค
import { lazyWithPreload } from "react-lazy-with-preload";
const UserList = lazyWithPreload(() => import('./components/UserList'))
function App() {
const [isClicked, setIsClicked] = useState(false)
return (
<div>
{isClicked && <UserList />}
<button onMouseOver={() => UserList.preload()} onClick={() => setIsClicked(true)}
>userlistํ์</button>
</div>
)
}
MouseOver
ํ์ ๋ UserList
์ปดํฌ๋ํธ๋ฅผ ๋ถ๋ฌ์ค๊ณ , Click
ํ์ ๋ ํด๋น ์ปดํฌ๋ํธ๊ฐ ๋ณด์ฌ์ง๋๋ก ํจํ ์ปดํฌ๋ํธ ๋ด์์ ํน์ state๊ฐ ๋ณ๊ฒฝ๋ ๋ ๋ง๋ค, useSelect๋ด์ state๋ณ๊ฒฝ์ด ์ ํ ์์์๋, ๋งค๋ฒ useSelect์ ๋ฆฌ๋ ๋๊ฐ ๋ฐ์ํ๋ ๋ฌธ์ ๊ฐ ๋ฐ์
createSelector
๋ state๊ฐ์ ์ ์ฅํ์ฌ, ๊ฐ์ด ๋ณํ ๋๋ง useSelector๊ฐ ๋ ๋๋ง ๋๋๋ก ํจ
// reducer.js
export const memoizedSelector = createSelector(
state => state,
value => value
)
const count = useSelector(memoizedSelector);