【发布时间】:2021-03-27 02:50:25
【问题描述】:
我的应用程序有一个用户输入查询以向 Pokemon API 发出请求并呈现响应数据。
如果用户输入数据库中不存在的查询,它将触发错误边界和Try Again 按钮,通过重置查询状态从错误中恢复并让用户重新提交不同的查询。这是预期的行为。
但是,在我当前的设置下,当用户的查询没有任何匹配项时,控制台将显示GET https://pokeapi.co/api/v2/pokemon/foo 404 和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>
);
};
【问题讨论】:
-
请在您的问题正文中发布一组最小化的工作代码。将来,您的链接可能不再有效,因此我们希望该问题能够独立存在。
-
@y2bd 没问题,我刚刚添加了代码。
-
不能在
handlePokemonFetch中的.catch语句中处理吗? -
@WebbH React-Query 期望一个失败的承诺,所以没有 catch 方法,因为它将使它成为一个已解决的承诺。
标签: reactjs react-hooks react-hook-form react-query react-error-boundary