๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Redux

[Redux] 7. ๋ฆฌ๋•์Šค useSelector ์ตœ์ ํ™”

๐Ÿ™ ์ด๋ฒˆ ์žฅ์˜ ๋ชฉํ‘œ

useSelector๋กœ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ตœ์ ํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ฐฐ์šด๋‹ค.

์ปดํฌ๋„ŒํŠธ ๋ฆฌ๋ Œ๋”๋ง ์—ฌ๋ถ€ ํ™•์ธํ•˜๊ธฐ

๋จผ์ €, ์ปดํฌ๋„ŒํŠธ์˜ ๋ฆฌ๋ Œ๋”๋ง ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ๋ฆฌ์•กํŠธ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ๋ฅผ ์„ค์น˜ํ•œ๋‹ค.

๐Ÿ‘‰ ๋ฆฌ์•กํŠธ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ ์„ค์น˜ํ•˜๊ธฐ

๋„๊ตฌ๋ฅผ ์„ค์น˜ํ•œ ๋’ค ๋ธŒ๋ผ์šฐ์ €์—์„œ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ฆฌ์•กํŠธ ํƒญ์ด ์ƒ์„ฑ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

์—ฌ๊ธฐ์„œ ์™ผ์ชฝ์— ์žˆ๋Š” ํ†ฑ๋‹ˆ๋ฐ”ํ€ด ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์„ค์ • ์ฐฝ์ด ํ™”๋ฉด์— ํ‘œ์‹œ๋œ๋‹ค.

์„ค์ • ์ฐฝ์—์„œ Highlight updates~~~๋ฅผ ์ฒดํฌํ•ด์ฃผ๋ฉด~?!

์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง๋ ๋•Œ๋งˆ๋‹ค ํ…Œ๋‘๋ฆฌ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

ํˆฌ๋‘๋ฆฌ์ŠคํŠธ ํŽ˜์ด์ง€ ์‚ดํŽด๋ณด๊ธฐ

์ด์ „์— ๋งŒ๋“ค์—ˆ๋˜ ํˆฌ๋‘๋ฆฌ์ŠคํŠธ ํŽ˜์ด์ง€๋ฅผ ์‚ดํŽด๋ณด๋ฉด์„œ ์ปดํฌ๋„ŒํŠธ ์ตœ์ ํ™” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์ž

ํŽ˜์ด์ง€์—์„œ +, - ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ๋ณด๋ฉด ํ•  ์ผ ๋ชฉ๋ก์€ ๋ฆฌ๋ Œ๋”๋ง ๋˜์ง€ ์•Š๋Š”๋‹ค. 

ํ•˜์ง€๋งŒ ํ•  ์ผ ๋ชฉ๋ก์˜ ํ•ญ๋ชฉ์„ ํด๋ฆญํ•ด๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ† ๊ธ€ ๋  ๋•Œ๋งˆ๋‹ค ์นด์šดํ„ฐ๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ธฐ๋ณธ์ ์œผ๋กœ, useSelector๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด ๋ฆฌ๋•์Šค ์Šคํ† ์–ด์˜ ์ƒํƒœ๊ฐ€ ๋ฐ”๋€Œ์—ˆ์„ ๋•Œ๋งŒ ๋ฆฌ๋ Œ๋”๋ง ๋œ๋‹ค.

TodosContainer์˜ ๊ฒฝ์šฐ todos ๋ฐฐ์—ด์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด useSelector๋กœ ๊ฐ์‹ธ์คฌ๋‹ค.

const todos = useSelector(state => state.todos);

๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— +, - ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ์„œ ์นด์šดํ„ฐ ๊ฐ’์ด ๋ณ€๊ฒฝ๋ผ๋„ todos ๊ฐ’์—” ๋ณ€ํ™”๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— TodosContainer๋Š” ๋ฆฌ๋ Œ๋”๋ง ๋˜์ง€ ์•Š๋Š”๋‹ค.

 

ํ•˜์ง€๋งŒ CounterContainer๋„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด useSelector๋ฅผ ์ ์šฉํ–ˆ๋Š”๋ฐ๋„ number์™€ diff๊ฐ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์•„๋„ ๋ฆฌ๋ Œ๋”๋ง์ด ๋ฐœ์ƒํ•œ๋‹ค. TodosContainer๊ณผ์˜ ์ฐจ์ด์ ์ด ๋ญ˜๊นŒ?

const { number, diff } = useSelector(state => ({
        number: state.counter.number,
        diff: state.counter.diff
    }));

์–ผํ• ๋ณด๋ฉด ๋‘ ์ปดํฌ๋„ŒํŠธ ๊ฐ„์˜ ์ฐจ์ด๊ฐ€ ์—†๋Š”๊ฒƒ ๊ฐ™์ง€๋งŒ

CounterContainer์—์„œ๋Š” ์‚ฌ์‹ค์ƒ useSelector Hook์„ ํ†ตํ•ด ๋งค๋ฒˆ ๋ Œ๋”๋ง ๋  ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ์šด ๊ฐ์ฒด { number, diff }๊ฐ€ ์ƒ์„ฑ๋˜๊ณ  ์žˆ๋‹ค.

๐Ÿ‘‰ ์ƒํƒœ๊ฐ€ ๋ฐ”๋€Œ์—ˆ๋Š”์ง€ ๋ฐ”๋€Œ์ง€ ์•Š์•˜๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์—†์–ด ๋ Œ๋”๋ง์ด ๊ณ„์† ์ผ์–ด๋‚˜๊ฐœ ๋œ๋‹ค.

 

์ด๋ฅผ ์ตœ์ ํ™”ํ•˜๊ธฐ ์œ„ํ•ด์„  ๋‘๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.

 

1. state๋ณ„๋กœ useSelector๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

const number = useSelector(state => state.counter.number);
const diff = useSelector(state => state.counter.diff);

๐Ÿ‘‰ number๋‚˜ diff๊ฐ€ ๋ณ€๊ฒฝ๋์„ ๋•Œ๋งŒ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง ๋œ๋‹ค

 

2. react-redux์˜ shallowEqual ํ•จ์ˆ˜๋ฅผ useSelector์˜ ๋‘๋ฒˆ์งธ ์ธ์ž๋กœ ์ „๋‹ฌํ•œ๋‹ค.

const { number, diff } = useSelector(
	state => ({
        number: state.counter.number,
        diff: state.counter.diff
    }),
	shallowEqual    
);

์›๋ž˜ useSelector์˜ ๋‘๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” equalityFn์ด๋‹ค.

โ“ equalityFn๋Š” ์ด์ „ ๊ฐ’๊ณผ ๋‹ค์Œ ๊ฐ’์„ ๋น„๊ตํ•ด ๊ฒฐ๊ณผ๊ฐ’์ด true์ด๋ฉด ๋ฆฌ๋ Œ๋”๋ง ํ•˜์ง€ ์•Š๊ณ  false๊ฐ€ ๋‚˜์˜ค๋ฉด ๋ฆฌ๋ Œ๋”๋ง์„ ์ง„ํ–‰ํ•œ๋‹ค. 

๊ทธ๋ฆฌ๊ณ  shallowEqual๋Š” react-redux์— ๋‚ด์žฅ๋ผ์žˆ๋Š” ํ•จ์ˆ˜๋กœ ๊ฐ์ฒด ์•ˆ์˜ ๊ฐ€์žฅ ๊ฒ‰์— ์žˆ๋Š” ๊ฐ’๋“ค์„ ๋ชจ๋‘ ๋น„๊ตํ•ด์ค€๋‹ค.

์—ฌ๊ธฐ์„œ ๊ฐ€์žฅ ๊ฒ‰์— ์žˆ๋Š” ๊ฐ’์˜ ์˜๋ฏธ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ๊ถ๊ธˆํ•ด์งˆ ๊ฒƒ์ด๋‹ค. ์ด์— ๋Œ€ํ•œ ์˜ˆ์‹œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

 

๋งŒ์ผ, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฐ์ฒด๊ฐ€ ์žˆ๋‹ค๋ฉด

const object = {
  a: {
    x: 3,
    y: 2,
    z: 1
  },
  b: 1,
  c: [{ id: 1 }]
}

 

๊ฐ€์žฅ ๊ฒ‰์— ์žˆ๋Š” ๊ฐ’์€ object.a, object.b, object.c์ด๋‹ค.

shallowEqual๋Š” ํ•ด๋‹น ๊ฐ’๋“ค๋งŒ ๋น„๊ตํ•œ๋‹ค.

object.a ๋‚ด์— ์žˆ๋Š” x, y, z๋‚˜ object.c[0]๋Š” ๋น„๊ต ๋Œ€์ƒ์— ํฌํ•จ๋˜์ง€ ์•Š๋Š”๋‹ค.

 

์ด์™€ ๊ฐ™์€ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•ด์„œ ์ตœ์ ํ™”๋ฅผ ํ•ด์ฃผ๋ฉด ์ปดํฌ๋„ŒํŠธ์˜ ๋ฆฌ๋ Œ๋”๋ง์„ ์ตœ์†Œํ™” ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์ฐธ๊ณ 

๋ฒจ๋กœํผํŠธ์™€ ํ•จ๊ป˜ํ•˜๋Š” ๋ชจ๋˜ ๋ฆฌ์•กํŠธ https://react.vlpt.us/redux/08-optimize-useSelector.html