๐ "React์์ ๋ถํ์ํ re-rendering component ๊ทธ๋ง!!"ํ์คํ ๋ฆฌ
๐ ํด๋์ค ์ปดํฌ๋ํธ ์์ฑ
๐ฉ ์์ ์ปดํฌ๋ํธ()
์ ํญ๋ชฉ๊ณผ ์ด์ ํญ๋ชฉ/์ํ๋ฅผ ๋น๊ตํ์ฌ ์ฐจ์ด๊ฐ ์์ผ๋ฉด ๊ตฌ์ฑ ์์๊ฐ ๋ ๋๋ง๋ฉ๋๋ค.
๋น๊ตํ๋ค?? ๊ทธ๋ฌ๋ ๊ทธ๋ค์ ๋น๊ตํ๋ ๋ฐฉ๋ฒ??
<< React์์ ๋ ๋๋งํ๋ ๊ฒฝ์ฐ >>
- state changes
- parent component renders
- props changes
- shouldcomponentUpdate function returns true (I'll explain about it later)
- forceUpdate
์ซ์ 1๊ณผ 2์ ๊ฒฝ์ฐ React๋ shallow compare์ ํตํด ๋ ๋๋งํ ์ง ์ฌ๋ถ๋ฅผ ๊ฒฐ์ ํฉ๋๋ค.
์์ ๋น๊ต๋ ๋ฌด์์ ๋๊น?
์ฒ์์๋ ์ฐธ์กฐ๊ฐ ๋ฌด์์ธ์ง ์์์ผ ํฉ๋๋ค.
โผ from this website
๋ณต์ฌ๋ ์ปต์ ์ปคํผ๋ฅผ ๋ถ์ผ๋ฉด ์๋ณธ ์ปต๋ ํจ๊ป ์ฑ์์ง๋๋ค(๋ ๋ฐ์ดํฐ๊ฐ ๋์ผํ ๋ฉ๋ชจ๋ฆฌ ํ ๋น ๊ณต๊ฐ์ ์๊ธฐ ๋๋ฌธ)
๋ณต์ฌํ ์ปต์ ์ปคํผ๋ฅผ ๋ถ์ผ๋ฉด ์๋ ์ปต์ด ์ฌ์ ํ ๋น์ด ์์
Javascript์์ ๊ธฐ๋ณธ ๋ฐ์ดํฐ ์ ํ(String, Number, Bigint, Boolean, Undefined, Symbol)์ ๊ฐ์ผ๋ก ์ ๋ฌ๋๊ณ Object, Array๋ ์ฐธ์กฐ๋ก ์ ๋ฌ๋ฉ๋๋ค.
์์งํ ์์ ๋ฐ์ดํฐ ํ์ ๊ณผ ๋น๊ตํ๋ ๊ฒ์ ๊ทธ๋ฆฌ ์ด๋ ต์ง ์์ง๋ง Object์์ ๋น๊ต์ ์ ๊ฒฝ์ ์จ์ผ ํฉ๋๋ค.
๊ฐ์ฒด ์ฐธ์กฐ์ ๊ฒฝ์ฐ๋ ๋์ผํฉ๋๋ค.
import shallowCompare from 'react-addons-shallow-compare';
const a = { country: "poland", country2: "japan" }
const b = a
console.log(shallowEqual(a, b))
// true
๊ฐ์ฒด ์ฐธ์กฐ์ ๊ฒฝ์ฐ๊ฐ ๋ค๋ฆ
import shallowCompare from 'react-addons-shallow-compare';
const a = { country: "poland", country2: "japan" }
const b = { country: "poland", country2: "japan" }
console.log(shallowEqual(a, b))
// true
import shallowCompare from 'react-addons-shallow-compare';
const a = {
country: "poland",
coountry2: {
city1: "tokyo",
city2: "osaka"
}
}
const b = {
country: "poland", // country is primitive type, scalar data is the same -> true
country2: { // country2 is object, so reference is different -> false
city1: "tokyo",
city2: "osaka"
}
}
console.log(shallowEqual(a, b))
// โญ false
๐ฉ shouldComponentUpdate()
๐ฆ so it is ok all components are pure component, isn't it?
๐ฉโ๐ป no, because cost of comparing old and new state/props is high
๐ฆ what should I do then?
๐ฉโ๐ป just decide comparing condition by yourself via "shouldComponentUpdate()"
์ค์ ๋ก PureComponent๋ shouldComponentUpdate()๋ฅผ ํตํด ๋๊ตฐ๊ฐ(ํ์ด์ค๋ถ ํ์ฌ์ ๋๊ตฐ๊ฐ)์ ์ํด ๊ตฌํ๋ ๊ตฌ์ฑ ์์์ ๊ฐ์ต๋๋ค.
// something like that
class PureComponent extends React.Component {
shouldComponentUpdate(nextProps, nextState) {
return !(shallowEqual(this.props, nextProps) && shallowEqual(this.state, nextState));
}
โฆ
}
๐ ๊ธฐ๋ฅ์ ๊ตฌ์ฑ ์์ ์์ฑ
2022๋ ์ฐ๋ฆฌ๋ ์ด ์ธ๋
๐ฉ ๋ฐ์.๋ฉ๋ชจ
PureComponent() + shouldComponentUpdate()์ ๊ฐ์ต๋๋ค.
// if new props changes, this component will be rendered
const Button = React.memo(props => {
return <div>{props.value}</div>
})
// if you put second argument, it is like shouldComponentUpdate()
const Button = React.memo(
props => {
return <div>{props.value}</div>
},
(nextProps, prevProps) => {
return nextProps.value === prevProps.value
}
)
๐ฉ ์ฌ์ฉ๋ฉ๋ชจ
๐ฆ what is useMemo? it is the same of React.memo?
๐ฉโ๐ป no, similar though. React.memo is added by React version16.6, and then React hook is added by version 16.8, useMemo as well.
๐ฆ aha
๐ฉโ๐ป useMemo renders only when props changes because it remembers calculation result
// when only "products props" changes, this component renders
const Component: React.FC = ({ products }) => {
const soldoutProducts = React.useMemo(() => products.filter(x => x.isSoldout === true), [products])
}
๐ฉ useCallback
๋ถ๋ชจ ์ปดํฌ๋ํธ๊ฐ ์์ ์ปดํฌ๋ํธ์๊ฒ ํจ์์ props๋ฅผ ๋๊ธฐ๋ฉด ์๋ก์ด ํจ์(์ฌ์ค ํจ์๋ ๊ฐ์ฒด์ ํ๋์ผ ๋ฟ)๊ฐ ๋ง๋ค์ด์ง๋ค.
๊ทธ๊ฒ ๋๋ฌธ์ ์์ ๊ตฌ์ฑ ์์๋ ์ด ์๋ก์ด ๊ธฐ๋ฅ์ด ์ด์ ๊ธฐ๋ฅ๊ณผ ๋ค๋ฅด๋ค๋ ๊ฒ์ ์ธ์ํ๊ณ ์ฌํ๊ฒ๋ ๋ค์ ๋ ๋๋งํฉ๋๋ค.
โ ์์/๋ถ๋ชจ ๊ตฌ์ฑ ์์ ๊ฐ์ ๋ํ
๐จ Parentใre-renderiiingggg!! And now I recreated function that I have !!ใ
๐ผ ChildใMom!! Give me your function as props!!ใ
๐จ Parentใok I give you my function!ใ
๐ผ Childใwell now I need to confirm this objectโs memory address is the same as object that I got before โฆ. Hmmm different address, I also re-rendering!!!ใ
์ด๋ฌํ ๋ถํ์ํ ์ฌ๋ ๋๋ง์ ๋ฐฉ์งํ๋ ค๋ฉด useCallback์ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
Reference
์ด ๋ฌธ์ ์ ๊ดํ์ฌ(๐ "React์์ ๋ถํ์ํ re-rendering component ๊ทธ๋ง!!"ํ์คํ ๋ฆฌ), ์ฐ๋ฆฌ๋ ์ด๊ณณ์์ ๋ ๋ง์ ์๋ฃ๋ฅผ ๋ฐ๊ฒฌํ๊ณ ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ ๋ณด์๋ค https://dev.to/kaziusan/history-of-stop-unnecessary-re-rendering-component-in-react--146fํ ์คํธ๋ฅผ ์์ ๋กญ๊ฒ ๊ณต์ ํ๊ฑฐ๋ ๋ณต์ฌํ ์ ์์ต๋๋ค.ํ์ง๋ง ์ด ๋ฌธ์์ URL์ ์ฐธ์กฐ URL๋ก ๋จ๊ฒจ ๋์ญ์์ค.
์ฐ์ํ ๊ฐ๋ฐ์ ์ฝํ ์ธ ๋ฐ๊ฒฌ์ ์ ๋ (Collection and Share based on the CC Protocol.)
์ข์ ์นํ์ด์ง ์ฆ๊ฒจ์ฐพ๊ธฐ
๊ฐ๋ฐ์ ์ฐ์ ์ฌ์ดํธ ์์ง
๊ฐ๋ฐ์๊ฐ ์์์ผ ํ ํ์ ์ฌ์ดํธ 100์ ์ถ์ฒ ์ฐ๋ฆฌ๋ ๋น์ ์ ์ํด 100๊ฐ์ ์์ฃผ ์ฌ์ฉํ๋ ๊ฐ๋ฐ์ ํ์ต ์ฌ์ดํธ๋ฅผ ์ ๋ฆฌํ์ต๋๋ค