我的应用程序让用户输入查询以向 Pokemon API 发出请求,并呈现响应数据。
如果用户输入了数据库中不存在的查询,它将触发错误边界和一个Try Again
按钮,通过重置查询状态并让用户重新提交不同的查询来从错误中恢复。这是预期的行为。
但是,使用我当前的设置,当用户的查询没有任何匹配项时,控制台将显示GET https://pokeapi.co/api/v2/pokemon/foo 404
and Uncaught (in promise) Error: Request failed with status code 404
。但是,用户没有看到此错误。没有什么可以告诉用户他们的查询没有任何匹配项。我的目标是获得更明确的用户体验,告诉用户他们提交的请求没有任何匹配项,然后单击Try Again
按钮重置输入并提交新查询。我相信,这就是错误边界应该做的。
我正在使用以下库:React Query, React Hook Form, React Error Boundary
. 有人建议我使用 React Query 的onError
回调来记录错误并设置属性useErrorBoundary: true
。仍然没有运气。
这是一个演示预期行为的工作示例。https://epic-react-exercises.vercel.app/react/hooks/3
这是我的尝试。请让我知道如何解决这个问题。https://codesandbox.io/s/pokedex-5j1jf
const ErrorFallback = ({ error, resetErrorBoundary }) => {
return (
<div role="alert">
<p>Something went wrong:</p>
<pre style={{ color: "red" }}>{error.message}</pre>
<button onClick={resetErrorBoundary}>Try again</button>
<p>This error was caught by the error boundary!</p>
</div>
);
};
const searchSchema = yup.object().shape({
pokemonName: yup.string().required()
});
const App = () => {
const [query, setQuery] = useState("");
const [pokemonCharacter, setPokemonCharacter] = useState({});
const { register, handleSubmit, watch, errors } = useForm({
resolver: yupResolver(searchSchema)
});
const handlePokemonFetch = () => {
return axios(`https://pokeapi.co/api/v2/pokemon/${query}`).then((res) => {
setPokemonCharacter(res.data);
});
};
const { loading, error } = useQuery("pokemon", handlePokemonFetch, {
refetchOnWindowFocus: false,
enabled: false,
useErrorBoundary: true,
onError: (error) => console.log(error)
});
console.log(watch(pokemonCharacter));
return (
<div>
<div>
<form onSubmit={handleSubmit(handlePokemonFetch)}>
<label htmlFor="Pokemon">Pokémon Character</label>
<input
type="text"
name="pokemonName"
ref={register}
onChange={(event) => setQuery(event.target.value)}
/>
{errors.pokemonName && <span>This field is required</span>}
{error && <p>Error occurred: {error.message}</p>}
<button type="submit">Search Pokémon</button>
</form>
</div>
<ErrorBoundary
FallbackComponent={ErrorFallback}
onReset={() => {
setQuery("");
}}
resetKeys={[query]}
>
<div>
{loading && <p>Loading...</p>}
<PokemonInfo pokemonCharacter={pokemonCharacter} />
</div>
</ErrorBoundary>
<ReactQueryDevtools initialIsOpen={true} />
</div>
);
};