我有一个简单的主细节场景,在左侧,我通过REST服务加载使用useSwr的城市列表,然后在右侧,我有一个城市细节窗口,它也使用useSwr加载单个城市(从单击左侧或首次加载).

在下面的代码中,我调用useEffect函数,然后在状态设置调用(setSelectedCityId)中使用从useSwr检索到的数据.

这是可行的,而且总是有与cities数组相关的数据,但我想知道是否可以保证useEffect的函数在悬念promise 完成后运行(看起来是这样的).

以下是我的简单代码:

import { Suspense, useEffect, useState, useTransition } from "react";
import useSwr from "swr";

const fetcher = (...args) => fetch(...args).then((res) => res.json());

function CityDetailFallback() {
  return <div>Loading (CityDetail)</div>;
}

function CityDetail({ selectedCityId }) {

  function CityDetailUI({ selectedCityId }) {
    const { data: city } = useSwr(
      selectedCityId
        ? `http://localhost:3000/api/city/${selectedCityId}`
        : null,
      fetcher,
      {
        suspense: true,
      }
    );
    
    if (!city) {
      return <div>loading city...</div>
    }
    
    return (
      <div className="row">
        <div className="col-9">
          <div>{JSON.stringify(city)} </div>
        </div>
      </div>
    );
  }

  return (
    <Suspense fallback={<CityDetailFallback />}>
      <CityDetailUI selectedCityId={selectedCityId}></CityDetailUI>
    </Suspense>
  );
}

function CityList({
  setSelectedCityId
}) {
  //
  const { data: cities } = useSwr("http://localhost:3000/api/city", fetcher, {
    suspense: true,
  });

  useEffect(() => {
    setSelectedCityId(cities[0].id);
  }, []);

  return (
    <div className="col-3">
      {cities.map((city) => {
        return (
          <div key={city.id}>
            <button
              onClick={(e) => {
                setSelectedCityId(city.id);
              }}
            >
              {city.city}
            </button>
          </div>
        );
      })}
    </div>
  );
}

export default function App() {
  const [selectedCityId, setSelectedCityId] = useState();

  return (
    <div className="container">
      <a href="/">Site Root</a>
      <hr />

      <Suspense fallback={<div>Loading...</div>}>
        <div className="row">
          <div className="col-3">
            <b>CITY LIST</b>
            <hr />
            <CityList
              setSelectedCityId={setSelectedCityId}
              selectedCityId={selectedCityId}
            />
          </div>
          <div className="col-9">
            <div>
              <b>CITY DETAIL (TOP ROW SELECTED AUTOMATICALLY)</b>
              <hr />
              <CityDetail selectedCityId={selectedCityId} />
            </div>
          </div>
        </div>
      </Suspense>
    </div>
  );
}

注意:我无法创建代码Sandbox ,因为当前useSwr中有一个关于悬念的bug.https://github.com/vercel/swr/issues/1906我目前正在使用Create React应用程序进行测试,并为REST调用使用一个虚拟api端点.抱歉:(

推荐答案

是的,在React 18useEffect中,当树一致时总是运行.因此,只有在树准备就绪且未暂停后,效果才会开火.

Reactjs相关问答推荐

在一个地方调用函数会影响其他地方调用该函数

在Reaction中单击时,按钮未按预期工作

单击按钮时在子元素中不显示任何内容-react

如何在react 流中使用文本区域和改变 node 的输入大小?

FireBase未与Reaction应用程序连接

对搜索引擎优化来说,react 头盔的异步足够了吗?

如何从react 18-nextjs 14应用程序路由中的客户端组件呈现服务器组件?

子路径上未定义useMatches句柄

当useEffect和onClick处理程序都调用useCallback函数时,有没有办法对useEffect产生额外的影响?

在Reaction中的第一次装载时,Use Effect返回空数组

Mantine DatePickerInput呈现错误

React路由dom布局隐藏内容

预期无限重新渲染但没有发生

获取更多数据后更新 DOM,而不刷新 React.js 中的页面

Primereact 的日历组件在每个月 12 日之后使用非唯一键生成

损坏的图像 React useState

如何使用样式化函数为 TextField 的输入组件设置样式

React Router v6 - 访问嵌套路由和处理手写 url 的正确方法

设置 Material UI 表格默认排序

在状态中存储多个选定的选项