본문 바로가기

FrontEnd

[Epic React] async 훅 사용 시 하나의 state를 사용하는 이유

반응형

리액트

state / loading / error 각각 다른 상태로 만들 경우.

데이터를 세팅하고 상태를 업데이트 하는 순서를 지키지 않으면 오류가 발생한다.

(상태는 바뀌었으나 데이터가 없으면 오류 발생)

널에 접근함

 // useEffect hooks...
 React.useEffect(() => {
    if (!pokemonName) {
      return
    }
    setStatus('pending')
    fetchPokemon(pokemonName).then(
      pokemon => {
        setPokemon(pokemon)
        setStatus('resolved')
      },
      error => {
        setError(error)
        setStatus('rejected')
      },
    )
  }, [pokemonName])
  
  
  
  // ... jsx part
    if (status === 'idle') {
    return 'Submit a pokemon'
  } else if (status === 'pending') {
    return <PokemonInfoFallback name={pokemonName} />
  } else if (status === 'rejected') {
    return (
      <div>
        There was an error:{' '}
        <pre style={{whiteSpace: 'normal'}}>{error.message}</pre>
      </div>
    )
  } else if (status === 'resolved') {
    return <PokemonDataView pokemon={pokemon} />
  }

  throw new Error('This should be impossible')

연관되어있는 데이터들을 하나의 state 객체로 관리한다 (일반적인 해법)

  const [state, setState] = React.useState({
    status: 'idle',
    pokemon: null,
    error: null,
  })
  const {status, pokemon, error} = state

  React.useEffect(() => {
    if (!pokemonName) {
      return
    }
    setState({status: 'pending'})
    fetchPokemon(pokemonName).then(
      pokemon => {
        setState({status: 'resolved', pokemon})
      },
      error => {
        setState({status: 'rejected', error})
      },
    )
  }, [pokemonName])

reducer 패턴을 사용하면 해당 문제는 자연스럽게 해결된다.

반응형