Using Suspense within our component isn't exactly ergonomic. Let's put all that logic into a reusable function so we can create resources anytime we need them and for any asynchronous interaction in our app.
In previous post, https://www.cnblogs.com/Answer1215/p/12006526.html, we have see how to use React.Suspense to handle data fetching, with fallback and ErrorBoundary.
In this post, we will refactor code to make a generic function to handle all use cases.
function createFetch(fetchFn) { let status = 'pending' let result let error let promise = fetchFn().then( p => { console.log('promise resolve') status = 'success' result = p }, e => { status = 'error' error = e }, ) return { read() { if (status === 'error') { throw error } if (status === 'pending') { throw promise // this API might change } if (status === 'success') { return result } }, } }
Use:
const promise = createFetch(() => fetchPokemon('pikachu')) function PokemonInfo() { console.log('PokemonInfo init') const pokemon = promise.read() return ( <div> <div className="pokemon-info__img-wrapper"> <img src={pokemon.image} alt={pokemon.name} /> </div> <PokemonDataView pokemon={pokemon} /> </div> ) }