【问题标题】:React suspense change detection mechanismReact 悬念变化检测机制
【发布时间】:2022-06-19 00:42:19
【问题描述】:

什么是悬念变化检测机制?我刚刚阅读了关于Suspense for Data Fetching (Experimental) 的文档,suspense 组件显示加载状态,直到嵌套组件准备好。 wrapPromise 函数用于包装获取功能以控制它的文档示例如下所列。所以: 当组件没有准备好时,它会抛出一个错误。

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;
      }
    }
  };
}

什么是悬念变化检测机制? Suspense 组件如何知道何时检查组件是否再次准备就绪?

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    孩子如何与父母沟通它需要暂停?通常,我们会将 setState 属性传递给子节点(例如 setLoading),子节点可以使用该属性将事件分派给父节点。但是这个“道具钻”:

    1. 杂乱无章的代码(尤其是在通过许多级别时)
    2. 需要越来越复杂的条件来同步加载状态(例如,在 childA 和 childB 加载状态为 false 之前,父级应显示加载组件)

    React 的解决方案很有趣... React Suspense 使用 javascript 现有的“throw”语句作为事件发射器,而不是传递许多 setState props,让孩子向父母发送事件。

    所以一个组件通过“抛出一个承诺”来告诉 React 暂停。然后,该异常将像异常一样“冒泡”到最近的悬念边界。所以悬念边界类似于抛出错误时的catch块。当一个悬念边界捕获一个抛出的 Promise 时,它​​将显示一个回退组件,直到该 Promise 被解决。当 promise 被解决时,React 将尝试重新渲染抛出 promise 的组件。

    抛出一个承诺是对异常冒泡的创造性使用。好处是它极大地减少了“道具钻探”,因为多层深的子组件可以简单地“抛出一个承诺”并且它会冒泡。并且编排加载序列变得更容易,因为多个兄弟姐妹可以抛出承诺,并且单个父 Suspense “Fallback”边界组件将显示,直到所有子承诺都得到解决(无需在父节点中定义许多条件)。虽然抛出 Promise 很方便,但它确实稍微改变了异常的语用学,explained 这个 Svelte 维护者雄辩地表达了这一点。

    关于 Suspense 的另一个有趣的注意事项是,抛出一个 Promise 并不会完全阻止执行!当 React Suspense 边界捕获到抛出的 Promise 并将后备组件提交到 DOM 时,它将继续尝试渲染组件树的其他部分。例如。在一个有 4 个子组件的组件中,其中子 1 抛出了一个 Promise——React 将捕获抛出的 Promise,提交一个后备元素,并在等待子 1 的 Promise 解决时继续尝试渲染其他 3 个子组件! (它甚至可能会继续尝试渲染子 1 的树的一部分。这个 SuspenseImage article 在“瀑布”部分中有关于这个主题的有趣注释)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-04-25
      • 2020-06-11
      • 1970-01-01
      • 1970-01-01
      • 2018-01-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多