React Suspense 如何确定组件是否准备好进行渲染?

6
我正在使用<React.Suspense>来进行数据获取,就像这个博客文章中所示。
来自React文档

Suspense允许你的组件在渲染之前等待某些内容。

并且在这个文档中更好地解释了。

React.Suspense允许你指定加载指示器,以防下面的组件树中的某些组件尚未准备好渲染。

我已经理解,如果一个组件尚未准备好渲染,那么在<React.Suspense>的fallback属性中指定的加载指示器将会显示出来。

然而我不明白React是如何检查组件是否准备好进行渲染的。根据这篇文档
随着更多的数据流入,React会尝试重新渲染,每次都有可能进一步"深入"。
这是否意味着当网络请求中有数据流入时,React也会重新渲染?
而是否在不断地检查组件是否准备好进行渲染?
1个回答

0

React.Suspense 依赖于一个特殊的包装器Promise。实际上,我们使用React.lazy作为这个包装器。如果你对这个包装器的工作原理感兴趣,请查看下面的代码片段。

// Boilerplate for the snippet, usually live in index.js
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);


// Main Component
function App() {
  return (
    <React.Suspense fallback={<LoadingPage />}>
      <RealPage />
    </React.Suspense>
  );
}

// Promise need to be monitored with a wrapper
function wrapPromise(promise) {
  let status = "pending";
  let result;
  let suspender = promise.then(
    (r) => {
      status = "success";
      result = r;
    },
    (e) => {
      status = "error";
      result = e;
    }
  );
  return {
    read() {
      if (status === "pending") {
        throw suspender;
      } else if (status === "error") {
        throw result;
      } else if (status === "success") {
        return result;
      }
    },
  };
}

// This is an example of a delayed process that
// uses `promise` to mock resource fetch
function delayedProcessExample() {
  // Wait for 3 seconds
  let promise = new Promise((resolve) => setTimeout(resolve, 3000))
    // Return an example result
    .then(() => "Hello, World!");

  return promise;
}

// The delayed process should be executed somewhere.
// If you put it in a component, then the App going to
// request indefinitely
const exampleResource = wrapPromise(delayedProcessExample());

// This is how you access the resource
function RealPage() {
  const exampleData = exampleResource.read();
  return <div>{exampleData}</div>;
}

// This is the fallback component
function LoadingPage() {
  return <div>Loading... Please Wait</div>;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.development.js"></script>
<div id="root"></div>

请注意,包装器抛出了suspender promise。这个表达式告诉React.Suspend有一个需要等待的promise。因此,基本上React.Suspend依赖于Promise作为异常来等待数据。

来源:


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接