diff --git a/src/__tests__/06.js b/src/__tests__/06.js index da1aaede9..e821e5988 100644 --- a/src/__tests__/06.js +++ b/src/__tests__/06.js @@ -2,8 +2,8 @@ import * as React from 'react' import {alfredTip} from '@kentcdodds/react-workshop-app/test-utils' import {render, screen} from '@testing-library/react' import userEvent from '@testing-library/user-event' -import App from '../final/06' -// import App from '../exercise/06' +// import App from '../final/06' +import App from '../exercise/06' beforeEach(() => jest.spyOn(window, 'fetch')) afterEach(() => window.fetch.mockRestore()) diff --git a/src/exercise/06.js b/src/exercise/06.js index ae69128b1..d29b991c2 100644 --- a/src/exercise/06.js +++ b/src/exercise/06.js @@ -1,31 +1,57 @@ // useEffect: HTTP requests // http://localhost:3000/isolated/exercise/06.js -import * as React from 'react' -// 🐨 you'll want the following additional things from '../pokemon': -// fetchPokemon: the function we call to get the pokemon info -// PokemonInfoFallback: the thing we show while we're loading the pokemon info -// PokemonDataView: the stuff we use to display the pokemon info -import {PokemonForm} from '../pokemon' +import * as React from 'react'; +import {ErrorBoundary} from 'react-error-boundary'; +import { + PokemonForm, + fetchPokemon, + PokemonInfoFallback, + PokemonDataView, +} from '../pokemon'; function PokemonInfo({pokemonName}) { - // 🐨 Have state for the pokemon (null) - // 🐨 use React.useEffect where the callback should be called whenever the - // pokemon name changes. - // 💰 DON'T FORGET THE DEPENDENCIES ARRAY! - // 💰 if the pokemonName is falsy (an empty string) then don't bother making the request (exit early). - // 🐨 before calling `fetchPokemon`, clear the current pokemon state by setting it to null - // 💰 Use the `fetchPokemon` function to fetch a pokemon by its name: - // fetchPokemon('Pikachu').then( - // pokemonData => { /* update all the state here */}, - // ) - // 🐨 return the following things based on the `pokemon` state and `pokemonName` prop: - // 1. no pokemonName: 'Submit a pokemon' - // 2. pokemonName but no pokemon: - // 3. pokemon: - - // 💣 remove this - return 'TODO' + 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}) + }, + ).catch((error) => { + setState({status: 'rejected', error}) + }); + + }, [pokemonName]); + + if (status === 'rejected') throw error; + + if (status === 'idle') { + return 'Submit a pokemon' + } else if (status === 'pending') { + return + } else if (status === 'resolved') { + return + } +} + +function ErrorFallback({error, resetErrorBoundary}) { + return ( +
+

Something went wrong:

+
{error.message}
+ +
+ ) } function App() { @@ -35,12 +61,22 @@ function App() { setPokemonName(newPokemonName) } + function handleReset() { + setPokemonName(''); + } + return (

- + + +
)