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

๐Ÿ’ปWEB FrontEnd/ํ”„๋ ˆ์ž„์›Œํฌ React

์„ฑ๋Šฅ๊ฐœ์„ (3) - batching, useTransition, useDeferredValue

batching

- state๋ณ€๊ฒฝํ•จ์ˆ˜๋ฅผ ์—ฐ๋‹ฌ์•„์„œ 3๊ฐœ ์‚ฌ์šฉํ•˜๋ฉด ์žฌ๋ Œ๋”๋ง๋„ ์›๋ž˜ 3๋ฒˆ ๋˜์–ด์•ผํ•˜์ง€๋งŒ ๋ฆฌ์•กํŠธ๋Š” ๋˜‘๋˜‘ํ•˜๊ฒŒ๋„ ์žฌ๋ Œ๋”๋ง์„ ๋งˆ์ง€๋ง‰์— 1ํšŒ๋งŒ ์ฒ˜๋ฆฌํ•ด์ค€๋‹ค. ์ด๋Ÿฐ ์žฌ๋ Œ๋”๋ง ๋ฐฉ์ง€๊ธฐ๋Šฅ์„ batching์ด๋ผ๊ณ  ํ•œ๋‹ค.

- ๊ทผ๋ฐ ๋ฌธ์ œ๋Š” ajax์š”์ฒญ, setTimeout์•ˆ์— state๋ณ€๊ฒฝํ•จ์ˆ˜๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ batching์ด ์ผ์–ด๋‚˜์ง€ ์•Š๋Š”๋‹ค. ๋ฆฌ์•กํŠธ 17๋ฒ„์ „๊นŒ์ง„ ๊ทธ๋Ÿฐ ์‹์œผ๋กœ ์ผ๊ด€์ ์ด์ง€ ์•Š๊ฒŒ ๋™์ž‘ํ–ˆ๋Š”๋ฐ18๋ฒ„์ „ ์ดํ›„ ๋ถ€ํ„ฐ๋Š” ์–ด๋”” ์žˆ๋“  ๊ฐ„์— ์žฌ๋ Œ๋”๋ง์€ ๋งˆ์ง€๋ง‰์— 1๋ฒˆ๋งŒ ๋œ๋‹ค. 

- batching ๋˜๋Š”๊ฒŒ ์‹ซ๊ณ  state๋ณ€๊ฒฝํ•จ์ˆ˜ ์‹คํ–‰๋งˆ๋‹ค ์žฌ๋ Œ๋”๋ง์‹œํ‚ค๊ณ  ์‹ถ์œผ๋ฉด flushSync๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ์“ฐ๋ฉด ๋œ๋‹ค. 

setCount(1) 
setName(2) 
setValue(3)   //์—ฌ๊ธฐ์„œ 1๋ฒˆ๋งŒ ์žฌ๋ Œ๋”๋ง๋จ

 

useTransition

useTransition๋กœ ์žฌ๋ Œ๋”๋ง์ด ์˜ค๋ž˜๊ฑธ๋ฆฌ๋Š” ๋ถ€๋ถ„์„ ๊ฐ์‹ธ๋ฉด ๋ Œ๋”๋ง์‹œ ๋ฒ„๋ฒ…์ด์ง€ ์•Š๊ฒŒ ํ•ด์ค€๋‹ค.

 

- startTransition() ํ•จ์ˆ˜ : state๋ณ€๊ฒฝํ•จ์ˆ˜ ๊ฐ™์€๊ฑธ ๋ฌถ์œผ๋ฉด ๊ทธ๊ฑธ ๋‹ค๋ฅธ ์ฝ”๋“œ๋“ค๋ณด๋‹ค ๋‚˜์ค‘์— ์ฒ˜๋ฆฌํ•ด์ค€๋‹ค.

import {useState, useTransition} from 'react'

let a = new Array(10000).fill(0)

function App(){
  let [name, setName] = useState('')
  let [isPending, startTransition] = useTransition()
  
  return (
    <div>
      <input onChange={ (e)=>{ 
        startTransition(()=>{
          setName(e.target.value) 
        })
      }}/>

      {
        a.map(()=>{
          return <div>{name}</div>
        })
      }
    </div>
  )
}

๊ทธ๋ž˜์„œ <input> ํƒ€์ดํ•‘๊ฐ™์ด ์ฆ‰๊ฐ ๋ฐ˜์‘ํ•ด์•ผํ•˜๋Š”๊ฑธ ์šฐ์„ ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค. 

๋ฌผ๋ก  ๊ทผ๋ณธ์ ์ธ ์„ฑ๋Šฅ๊ฐœ์„ ์ด๋ผ๊ธฐ๋ณด๋‹จ ํŠน์ •์ฝ”๋“œ์˜ ์‹คํ–‰์‹œ์ ์„ ๋’ค๋กœ ์˜ฎ๊ฒจ์ฃผ๋Š” ๊ฒƒ์ผ ๋ฟ์ด๋‹ค. 

 

- isPending : startTransition() ์œผ๋กœ ๊ฐ์‹ผ ์ฝ”๋“œ๊ฐ€ ์ฒ˜๋ฆฌ์ค‘์ผ ๋•Œ true๋กœ ๋ณ€ํ•˜๋Š” ๋ณ€์ˆ˜์ด๋‹ค.

{
  isPending ? "๋กœ๋”ฉ์ค‘๊ธฐ๋‹ค๋ฆฌ์…ˆ" :
  a.map(()=>{
    return <div>{name}</div>
  })
} 

์œ„์˜ ์ฝ”๋“œ๋Š” useTransition์œผ๋กœ ๊ฐ์‹ผ๊ฒŒ ์ฒ˜๋ฆฌ์™„๋ฃŒ๋˜๋ฉด <div>{name}</div> ์ด ๋ณด์ธ๋‹ค.

 

useDeferredValue

- startTransition()๋ž‘ ์šฉ๋„๊ฐ€ ๋น„์Šทํ•˜๋‹ค.

- ๊ทผ๋ฐ ์–˜๋Š” state ์•„๋‹ˆ๋ฉด ๋ณ€์ˆ˜ํ•˜๋‚˜๋ฅผ ์ง‘์–ด๋„ฃ์„ ์ˆ˜ ์žˆ๊ฒŒ ๋˜์–ด์žˆ๋‹ค. ๊ทธ๋ž˜์„œ ๊ทธ ๋ณ€์ˆ˜์— ๋ณ€๋™์‚ฌํ•ญ์ด ์ƒ๊ธฐ๋ฉด ๊ทธ๊ฑธ ๋Šฆ๊ฒŒ ์ฒ˜๋ฆฌํ•ด์ค€๋‹ค. 

import {useState, useTransition, useDeferredValue} from 'react'

let a = new Array(10000).fill(0)

function App(){
  let [name, setName] = useState('')
  let state1 = useDeferredValue(name)
  
  return (
    <div>
      <input onChange={ (e)=>{ 
          setName(e.target.value) 
      }}/>

      {
        a.map(()=>{
          return <div>{state1}</div>
        })
      }
    </div>
  )
}

 

useDeferredValue ์•ˆ์— state๋ฅผ ์ง‘์–ด๋„ฃ์œผ๋ฉด ๊ทธ state๊ฐ€ ๋ณ€๋™์‚ฌํ•ญ์ด ์ƒ๊ฒผ์„ ๋•Œ ๋‚˜์ค‘์— ์ฒ˜๋ฆฌํ•ด์ค€๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์ฒ˜๋ฆฌ๊ฒฐ๊ณผ๋Š” let state์— ์ €์žฅํ•ด์ค€๋‹ค.