Tự học ReactJS: Sử dụng useDebugValue

Chắc các bạn đã quen với React Devtools. Khi bạn viết một custom hook, bạn cần có một label cho nó trong React DevTools để dễ dàng debug được hook đó.

useDebugValue cho phép chúng ta đặt label cho custom hook của chúng ta như sau:

function useCount({initialCount = 0, step = 1} = {}) {
  React.useDebugValue({initialCount, step})
  const [count, setCount] = React.useState(0)
  const increment = () => setCount(c => c + 1)
  return [count, increment]
}

Ví dụ chúng ta có custom hook useMedia như sau:

import * as React from 'react'

function useMedia(query, initialState = false) {
  const [state, setState] = React.useState(initialState)
  // 🐨 call React.useDebugValue here.
  // 💰 here's the formatted label I use: `\`${query}\` => ${state}`

  React.useEffect(() => {
    let mounted = true
    const mql = window.matchMedia(query)
    function onChange() {
      if (!mounted) {
        return
      }
      setState(Boolean(mql.matches))
    }

    mql.addListener(onChange)
    setState(mql.matches)

    return () => {
      mounted = false
      mql.removeListener(onChange)
    }
  }, [query])

  return state
}

function Box() {
  const isBig = useMedia('(min-width: 1000px)')
  const isMedium = useMedia('(max-width: 999px) and (min-width: 700px)')
  const isSmall = useMedia('(max-width: 699px)')
  const color = isBig ? 'green' : isMedium ? 'yellow' : isSmall ? 'red' : null

  return <div style={{width: 200, height: 200, backgroundColor: color}} />
}

function App() {
  return <Box />
}

export default App

Khi bạn mở React Devtool để xem hook trong <Box /> component bạn sẽ thấy rằng thông tin các hook như hình sau:

Chúng ta có 3 hook useMedia nhưng chưa biết từng hook được apply như thế nào. Do đó, chúng ta có thể sử dụng useDebugValue để gán nhãn cho từng hook như sau:


Bạn có thể sử dụng useDebugValue cho hook useMedia như sau:

function useMedia(query, initialState = false) {
  const [state, setState] = React.useState(initialState)
  React.useDebugValue(`\`${query}\` => ${state}`)

  React.useEffect(() => {
    let mounted = true
    const mql = window.matchMedia(query)
    function onChange() {
      if (!mounted) {
        return
      }
      setState(Boolean(mql.matches))
    }

    mql.addListener(onChange)
    setState(mql.matches)

    return () => {
      mounted = false
      mql.removeListener(onChange)
    }
  }, [query])

  return state
}

Một điều lưu ý là useDebugValue chỉ sử dụng được trong custom hook để gán nhãn cho hook của bạn để bạn dễ debug hơn.

thaunguyen.com via Epic React by Kent C.Dodds

Leave a Reply

Your email address will not be published. Required fields are marked *