[React] Handle HTTP Errors with React

Unfortunately, sometimes a server request fails and we need to display a helpful error message to the user. In this lesson we’ll handle a promise rejection so we can collect that error information, and we’ll also learn how we can best display manage the state of our request so we have a deterministic render method to ensure we always show the user the proper information based on the current state of our React component.

A common mistake people make is to create a state variable called isLoading and set that to true or false. Instead, we’ll be using a status variable which can be set to idlependingresolved, or rejected. You can learn more about why this is important from Stop using isLoading booleans.

 

<body>
  <div id="root"></div>
  <script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
  <script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>
  <script src="https://unpkg.com/@babel/[email protected]/babel.js"></script>
  <script type="text/babel">
    function PokemonInfo({pokemonName}) {
      const [status, setStatus] = React.useState('idle')
      const [pokemon, setPokemon] = React.useState(null)
      const [error, setError] = React.useState(null)

      React.useEffect(() => {
        if (!pokemonName) {
          return
        }
        setStatus('pending')
        fetchPokemon(pokemonName).then(
          pokemonData => {
            setStatus('resolved')
            setPokemon(pokemonData)
          },
          errorData => {
            setStatus('rejected')
            setError(errorData)
          },
        )
      }, [pokemonName])

      if (status === 'idle') {
        return 'Submit a pokemon'
      }

      if (status === 'rejected') {
        return 'Oh no...'
      }

      if (status === 'pending') {
        return '...'
      }

      if (status === 'resolved') {
        return <pre>{JSON.stringify(pokemon, null, 2)}</pre>
      }
    }

    function App() {
      const [pokemonName, setPokemonName] = React.useState('')

      function handleSubmit(event) {
        event.preventDefault()
        setPokemonName(event.target.elements.pokemonName.value)
      }

      return (
        <div>
          <form onSubmit={handleSubmit}>
            <label htmlFor="pokemonName">Pokemon Name</label>
            <div>
              <input id="pokemonName" />
              <button type="submit">Submit</button>
            </div>
          </form>
          <hr />
          <PokemonInfo pokemonName={pokemonName} />
        </div>
      )
    }

    function fetchPokemon(name) {
      const pokemonQuery = `
        query ($name: String) {
          pokemon(name: $name) {
            id
            number
            name
            attacks {
              special {
                name
                type
                damage
              }
            }
          }
        }
      `

      return window
        .fetch('https://graphql-pokemon.now.sh', {
          // learn more about this API here: https://graphql-pokemon.now.sh/
          method: 'POST',
          headers: {
            'content-type': 'application/json;charset=UTF-8',
          },
          body: JSON.stringify({
            query: pokemonQuery,
            variables: {name},
          }),
        })
        .then(r => r.json())
        .then(response => response.data.pokemon)
    }

    ReactDOM.render(<App />, document.getElementById('root'))
  </script>
</body>

 

Guess you like

Origin www.cnblogs.com/Answer1215/p/12610062.html