gpt4 book ai didi

javascript - react : Avoid nondeterministic first render (hack with "mounted" state)

转载 作者:行者123 更新时间:2023-12-03 17:22:23 26 4
gpt4 key购买 nike

TL;DR React 有时会呈现加载状态,有时不会呈现,无需更改 UI。这可能是由于 batched updates .
我想知道下面的问题是否是由于批量更新造成的。如果答案是"is",我想知道是否有首选方法可以选择退出 React 中的批量更新以获得确定性的渲染行为。如果要跳过设置,请转到“实验”。

设置
See on CodeSandbox
enter image description here
这是设置,一个需要很长时间才能呈现的图表。只要渲染被阻塞。这里有三种不同的方式来呈现图表:

  • 一种是正常方式
  • 一个带有“已安装”渲染技巧的
  • 一个具有相同的“已安装”渲染技巧,但具有额外的 setTimeout

  • 选项 2 和 3 都有一个小的 useState检查它们是否已安装。我这样做是为了有条件地显示“加载”状态:
    function ChartWithMountHack({ data }: { data: Data }) {
    // initially not mounted
    const [isMounted, setIsMounted] = useState<boolean>(false);

    useEffect(() => {
    // "Now I've been mounted!"
    setIsMounted(true);
    }, []);

    return !isMounted ? <p>Loading</p> : <Chart data={data} />;
    }
    我这样做是因为我想显示“正在加载”状态而不是阻塞渲染,例如页面切换或三元渲染(例如 hasData ? <p>No data</p> : <Chart /> )会立即显示,而不是阻塞。 (如果有更好的方法,请告诉我!)

    实验
    现在,每个按钮将呈现三个选项/图表之一。同样,第二个和第三个图表有一个小技巧来检查它们是否已安装。
    尝试快速来回单击第一个按钮和第二个按钮。
    您会看到有时“带有 mount hack 的图表”会(“正确”)呈现“正在加载”状态,但有时它只是不呈现“正在加载” - 相反它会阻止渲染,直到图表完成呈现(跳过“加载”状态)。
    我认为这是由于渲染周期以及您是否在一个批处理周期中获得两个更新。 (第一个: isMounted === false -> 第二个: isMounted === true)
    我真的不知道如何重现这一点,因此标题中的“不确定性”。有时您还必须单击“重新生成数据”,然后单击来回。

    交叉检查
    选项 3(“带有超时挂载黑客的图表”)总是给我“加载”状态,这正是我想要的。与选项 2 的唯一区别是使用 setTimeoutuseEffect在哪里 isMounted设置为真。 setTimeout is used here to break out of the update batching.
    有没有更好的方法来退出批处理,所以 isMounted将始终以其初始值 ( false ) 呈现?使用 setTimeout这里感觉就像一个黑客。

    最佳答案

    React 具有处理这些事情的并发特性,例如 React Suspense 标签或者你使用像 Rxjs 这样的订阅库,它的订阅应该在 componentDidMount 和 componentWillUnmount 中完成以取消订阅数据。
    然后 isMounted 只是解决未决问题的方法,可能来自您正在使用的库,或者有时只是您的捆绑器/构建工具有点作用。
    最后,为了避免不必要的重新渲染,您可以使用 React.Memo 对组件进行 React memoization。
    请阅读更多关于这些的内容。

    关于javascript - react : Avoid nondeterministic first render (hack with "mounted" state),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66766149/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com