2. React State

React State์— ๋Œ€ํ•ด ๋ช…ํ™•ํ•˜๊ฒŒ ์ดํ•ดํ•˜๊ณ , ์ฝ”๋“œ ๋ฆฌํŒฉํ„ฐ๋ง ์˜๋„๋ฅผ ํŒŒ์•…ํ•˜๊ณ  ํก์ˆ˜ํ•˜์ž.

Thinking in React (React๋กœ ์‚ฌ๊ณ ํ•˜๊ธฐ)

Step 3: Find the minimal but complete representation of UI state

์ตœ์†Œํ•œ์˜ ์™„์ „ํ•œ UI state ์ฐพ๊ธฐ

Step 4: Identify where your state should live

state๊ฐ€ ์–ด๋””์— ์žˆ์–ด์•ผ ํ• ์ง€ ํŒŒ์•…ํ•˜๊ธฐ

Step 5: Add inverse data flow

์—ญ๋ฐฉํ–ฅ ๋ฐ์ดํ„ฐ ํ๋ฆ„ ์ถ”๊ฐ€ํ•˜๊ธฐ


Keyword

  • React state๋ž€?

  • DRY ์›์น™

  • SSOT(Single Source of Truth)

  • useState

  • 1๊ธ‰ ๊ฐ์ฒด(first-class object)๋ž€?

  • Lifting State Up


React์˜ State

  • React์˜ State๋Š” ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋™์ ์ธ ๋ฐ์ดํ„ฐ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฐ์ฒด๋‹ค.

  • State์˜ ๋ณ€๊ฒฝ์€ ์ปดํฌ๋„ŒํŠธ ๋ฆฌ๋ Œ๋”๋ง์„ ํŠธ๋ฆฌ๊ฑฐํ•œ๋‹ค.

  • ๋ฆฌ๋ Œ๋”๋ง์ด ๋ฐœ์ƒํ•˜๋ฉด ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋ฅผ ํฌํ•จํ•œ ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ๋„ ๋ฆฌ๋ Œ๋”๋ง๋œ๋‹ค.

  • ๋ชจ๋“  ๋ฐ์ดํ„ฐ๊ฐ€ State๊ฐ€ ๋˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.

DRY ์›์น™

Don't Repeat Yourself ์›์น™์€ ์ค‘๋ณต ์ฝ”๋“œ๋ฅผ ํ”ผํ•˜๊ณ  ์ฝ”๋“œ๋ฅผ ์žฌ์‚ฌ์šฉํ•  ๊ฒƒ์„ ๊ฐ•์กฐํ•˜๋Š” ์†Œํ”„ํŠธ์›จ์–ด ๋””์ž์ธ ์›์น™์ด๋‹ค.

  • ์ค‘๋ณต ๋กœ์ง์„ ํ•จ์ˆ˜๋‚˜ ํด๋ž˜์Šค๋ฅผ ํ™œ์šฉํ•ด ์žฌ์‚ฌ์šฉํ•œ๋‹ค.

  • React์˜ ๊ฒฝ์šฐ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์žฌ์‚ฌ์šฉํ•ด ์ฝ”๋“œ ์ค‘๋ณต์„ ์ตœ์†Œํ™”ํ•œ๋‹ค.

  • Custom Hooks๋ฅผ ํ™œ์šฉํ•ด ๊ณตํ†ต ๋กœ์ง์„ ๋ถ„๋ฆฌํ•œ๋‹ค.

SSOT(Single Source of Truth)

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋‚ด๋ถ€์˜ ๋ชจ๋“  ์ƒํƒœ ์ •๋ณด๋ฅผ ํ•˜๋‚˜์˜ ์†Œ์Šค์—์„œ ๊ด€๋ฆฌํ•˜์ž๋Š” ๊ฐœ๋…

์ฆ‰, ์ปดํฌ๋„ŒํŠธ ์ด๊ณณ์ €๊ณณ์—์„œ ์ƒํƒœ๋ฅผ ๋ฌด๋ถ„๋ณ„ํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜์ง€ ๋ง๊ณ  ํ•ด๋‹น ์ƒํƒœ์— ์˜์กดํ•˜๋Š” ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๋ฅผ ํฌํ•จํ•˜๋Š” ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜์ž๋Š” ์˜๋ฏธ, ๋˜๋Š” ์ „์—ญ ์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ†ตํ•ด ์™ธ๋ถ€ Store์—์„œ ๊ด€๋ฆฌ

useState

React Hooks์ค‘ ํ•˜๋‚˜๋กœ ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ์—์„œ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ํ•จ์ˆ˜

const [state, setState] = useState(initialState);
  • useState ํ•จ์ˆ˜๋Š” ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์ฒซ๋ฒˆ์งธ ์š”์†Œ๋Š” ํ˜„์žฌ ์ƒํƒœ ๊ฐ’, ๋‘๋ฒˆ์งธ๋Š” ์ƒํƒœ ์—…๋ฐ์ดํŠธ ํ•จ์ˆ˜

  • initialState๋Š” ์ƒํƒœ ์ดˆ๊ธฐ๊ฐ’์ด๋ฉฐ, ์ฒซ ๋ Œ๋”๋ง ์‹œ์—๋งŒ ์‚ฌ์šฉ๋œ๋‹ค.

  • setState ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ด ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด, ๋ณ€๊ฒฝ๋œ ์ƒํƒœ๋ฅผ ๋ฐ˜์˜ํ•˜๊ธฐ ์œ„ํ•ด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”๋œ๋‹ค.

1๊ธ‰ ๊ฐ์ฒด(first-class object)

Javascript์—์„œ์˜ ์ผ๊ธ‰ ๊ฐ์ฒด๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํŠน์ง•์„ ๊ฐ€์ง„ ๊ฐ์ฒด๋‹ค.

  1. ํ•จ์ˆ˜๋ฅผ ๋ณ€์ˆ˜์˜ ๊ฐ’์œผ๋กœ ํ• ๋‹นํ•  ์ˆ˜ ์žˆ๋‹ค. (ex. ํ•จ์ˆ˜ ํ‘œํ˜„์‹)

  2. ํ•จ์ˆ˜๋ฅผ ํ•จ์ˆ˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค. (ex. ์ฝœ๋ฐฑ ํ•จ์ˆ˜)

  3. ํ•จ์ˆ˜๋ฅผ ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜ ๊ฐ’์œผ๋กœ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. (ex. ํด๋กœ์ €)

์ผ๊ธ‰ ๊ฐ์ฒด์˜ ํŠน์ง•์œผ๋กœ ์ธํ•ด ์ฝœ๋ฐฑ ํ•จ์ˆ˜, ๊ณ ์ฐจ ํ•จ์ˆ˜ ๋“ฑ์˜ ๋‹ค์–‘ํ•œ ํŒจํ„ด์„ ํ†ตํ•ด ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

Lifting State Up

SSOP์—์„œ ์–ธ๊ธ‰ํ•œ ํ•˜๋‚˜์˜ ์†Œ์Šค์—์„œ ๊ด€๋ฆฌํ•˜์ž๋Š” ๊ฐœ๋…์„ ์ ์šฉํ•˜์—ฌ ์—ฌ๋Ÿฌ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋™์ผํ•œ ์ƒํƒœ๋ฅผ ๊ณต์œ ํ•ด์•ผ ํ•  ๊ฒฝ์šฐ ๊ณตํ†ต ์ปดํฌ๋„ŒํŠธ๋กœ State๋ฅผ ๋Œ์–ด์˜ฌ๋ฆฌ๋Š” Lifting State Up ๊ณผ์ •์ด ํ•„์š”ํ•˜๋‹ค.

  • ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์—์„œ State๋ฅผ ๊ด€๋ฆฌํ•˜๋ฏ€๋กœ ์ƒํƒœ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค. (ex. ํŠน์ • ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ํ•ด๋‹น ์ƒํƒœ ๊ณต์œ ๊ฐ€ ํ•„์š”ํ•  ๊ฒฝ์šฐ Props๋กœ ์ „๋‹ฌ)

  • Props Driling์„ ์ตœ์†Œํ™” ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • State์˜ ์ค‘๋ณต์„ ์ตœ์†Œํ™” ํ•  ์ˆ˜ ์žˆ๋‹ค.

Inverse Data Flow

React๋Š” ๋ฐ์ดํ„ฐ ์ „๋‹ฌ์ด ๋ถ€๋ชจ์—์„œ ์ž์‹์œผ๋กœ ํ•œ ์ชฝ์œผ๋กœ๋งŒ ํ๋ฅด๋Š” ๋‹จ๋ฐฉํ–ฅ ๋ฐ”์ธ๋”ฉ์˜ ํŠน์„ฑ์„ ๊ฐ€์ง€๋Š”๋ฐ, ์—ญ๋ฐฉํ–ฅ ๋ฐ์ดํ„ฐ ํ๋ฆ„์€ ์ด์— ๋Œ€๋น„๋˜๋Š” ๊ฐœ๋…์ด๋‹ค. ์ž์‹ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•  ๋• ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•˜๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธํ•œ๋‹ค.

function FilterableProductTable({ products }) {
  const [filterText, setFilterText] = useState('');
  const [inStockOnly, setInStockOnly] = useState(false);

  return (
    <div>
      <SearchBar 
        filterText={filterText} 
        inStockOnly={inStockOnly}
        onFilterTextChange={setFilterText}
        onInStockOnlyChange={setInStockOnly} />

// SearchBar.jsx

<input 
  type="text" 
  value={filterText} 
  placeholder="Search..." 
  onChange={(e) => onFilterTextChange(e.target.value)} />

Last updated