React HooksのTypeScriptによる型付け

比較的よく使うuseState/useReducer/useContextのTypeScriptによる型付け

Hooksの詳細についてはこちらを参照
Hooks API Reference – React

useState

import * as React from 'react'

export const UseStateExample = () => {
  const [count, setCount] = React.useState<number>(0)

  return (
    <div>
      <div>count: {count}</div>
      <div>
        <button onClick={() => setCount(count + 1)}>++</button>
      </div>
    </div>
  )
}

// 複数の値を1つのstateにまとめる場合
interface State {
  count: number
  message: string
}

const initialState: State = {
  count: 0,
  message: 'hi',
}

export const ComplexStateExample = () => {
  const [state, setState] = React.useState<State>(initialState)
  const { count, message } = state

  return (
    <div>
      <h1>{message}</h1>
      <div>count: {count}</div>
      <div>
        <button
          onClick={() =>
            setState({
              ...state,
              count: count + 1,
            })
          }
        >
          ++
        </button>
      </div>
    </div>
  )
}

useReducer

import * as React from 'react'

interface State {
  count: number
}

interface IncrementAction {
  type: 'increment'
}
interface ChangeAction {
  type: 'change'
  number: number
}
interface ResetAction {
  type: 'reset'
}
type Action = IncrementAction | ChangeAction | ResetAction

const reducer = (state: State, action: Action) => {
  switch (action.type) {
    case 'increment':
      return { count: state.count + 1 }
    case 'change':
      return { count: action.number }
    case 'reset':
      return { count: 0 }
    default:
      return { ...state }
  }
}

const initialState: State = {
  count: 0,
}

export const UseReducerExample = () => {
  const [state, dispatch] = React.useReducer(reducer, initialState)

  return (
    <div>
      <div>count: {state.count}</div>
      <div>
        <button onClick={() => dispatch({ type: 'increment' })}>++</button>
        <button onClick={() => dispatch({ type: 'change', number: 5 })}>
          to 5
        </button>
        <button onClick={() => dispatch({ type: 'reset' })}>reset</button>
      </div>
    </div>
  )
}

useContext

import * as React from 'react'

interface ExampleContextValue {
  message: string
  count: number
}

const initialContextValue: ExampleContextValue = {
  message: 'hello',
  count: 100,
}

const ExampleContext = React.createContext<ExampleContextValue>(
  initialContextValue,
)

export const UseContextExample = () => {
  const { message, count } = React.useContext(ExampleContext)
  return (
    <div>
      {message}: {count}
    </div>
  )
}