随着 React 19 的引入,如何在某些值更改时实现重新获取

问题描述 投票:0回答:1

React 19 将引入一个

use
钩子,这将使我们能够避免状态设置中的所有
useEffects
,但是如果我们想在某些状态更改时重新获取相同的值,单击按钮怎么办?

例如


  const [joke, setJoke] = useState([]);
  const [loading, setLoading] = useState(true);
  const [shouldRefetch, setShouldRefetch]= useState(false)
  useEffect(() => {
    const fetchJoke = async () => {
      try {
        const res = await fetch('https://api.chucknorris.io/jokes/random');
        const data = await res.json();
        setJoke(data);
        setLoading(false);
      } catch (error) {
        console.error(error);
      } finally {
        setLoading(false);
      }
    };
    fetchJoke();
  }, [shouldRefetch]);

据我所知,这是一种愚蠢的重新获取方法,它仅用于演示,但我们可以单击按钮更改状态并触发重新获取

const JokeItem = () => {
  const joke = use(apiCall());
  return (
    <div className="bg-blue-50 shadow-md p-4 my-6 rounded-lg">
      <h2 className="text-xl font-bold">{joke.value}</h2>
    </div>
  );
};

这就是 React 19 给我们带来的,在这种情况下我们如何触发重新获取?

到目前为止,唯一想到的就是强制重新渲染,或者最初调用它并将其设置为

useState
,然后创建一个执行重新获取的处理程序。

reactjs react-hooks
1个回答
0
投票

使用

use
,你仍然需要管理承诺本身,可能是在状态中。
use
旨在提供一种符合人体工程学的方式,通过直接使用 Promise 来挂钩 Suspense,而不是从根本上取代状态管理。当然,它确实让它变得更容易(不再跟踪加载状态)。

提供的

JokeItem
示例可能无法实现您想要的效果,因为每次承诺解析时,组件都会重新渲染,并且
apiCall()
将再次被调用,这可能会给出 new 未解决的承诺。 IE。它将处于瀑布循环中。

一个比较有代表性的例子是这样的:

import { use, useState, Suspense } from "react";

export default function App() {
  const [apiCallPromise, setApiCallPromise] = useState(() => apiCall());
  return (
    <Suspense fallback={"loading..."}>
      <JokeItem
        apiCallPromise={apiCallPromise}
        onRefreshClick={() => setApiCallPromise(apiCall())}
      />
    </Suspense>
  );
}

const apiCall = () => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({ value: "helo" });
    }, 1000);
  });
};

const JokeItem = ({ apiCallPromise, onRefreshClick }) => {
  const joke = use(apiCallPromise);

  return (
    <div className="bg-blue-50 shadow-md p-4 my-6 rounded-lg">
      <h2 className="text-xl font-bold">{joke.value}</h2>
      <button onClick={onRefreshClick}>Refresh</button>
    </div>
  );
};
© www.soinside.com 2019 - 2024. All rights reserved.