微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何从错误边界恢复中重置 React 状态?

如何解决如何从错误边界恢复中重置 React 状态?

我的应用程序有一个用户输入查询以向 Pokemon API 发出请求并呈现响应数据。

如果用户输入数据库中不存在的查询,它将触发错误边界和Try Again按钮以通过重置查询状态从错误中恢复并让用户重新提交不同的查询.这是预期的行为。

但是,根据我当前的设置,当用户查询没有任何匹配项时,控制台将显示 GET https://pokeapi.co/api/v2/pokemon/foo 404Uncaught (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>
  );
};

解决方法

我认为问题出在您使用错误边界的方式上。

如果我们查看 react-error-boundary 的文档,我们会看到以下内容:

最简单的使用方法是将其包裹在任何可能引发错误的组件周围。这也将处理该组件及其后代抛出的错误。

在您的示例中,引发错误的组件是呈现 ErrorBoundary 的组件。但为了使其正常工作,引发错误的组件应该是 ErrorBoundary 的子组件。

我创建了一个稍微不同的沙箱来说明这一点。 https://codesandbox.io/s/jovial-poincare-06e6v

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。