繁体   English   中英

在 React 中推迟 state 更新/重新渲染

[英]Defer state update / rerender in React

我创建了一个 React 组件,该组件向后端发送 GraphQL 查询以检索图像作为 base64 编码的字符串并在加载时显示它。 在那之前,它会显示一个小的加载微调器。 代码看起来或多或少像这样并且按预期工作:

const { data, loading, error } = useQuery(...)
const showImage = !loading && !error && data?.image?.base64
const showError = !loading && (error || !showImage)

return (
    <div>
        {loading && <img src={`/loading.gif`} />}
        {showError && <img src={`/error.png`} />}
        {showImage && <img src={`data:image/jpg;base64, ${data.image.base64}`}/>}
    </div>
)

但最重要的是,该控件还允许一些基本的图像操作(例如,将图像染成紫色的按钮),这是我用useState实现的。 本质上:

const [ purple, setPurple ] = useState(false)

const { data, loading, error } = useQuery(/* pass `purple` to backend */)
const showImage = !loading && !error && data?.image?.base64
const showError = !loading && (error || !showImage)

return (
    <div>
        {loading && <img src={`/loading.gif`} />}
        {showError && <img src={`/error.png`} />}
        {showImage && <img src={`data:image/jpg;base64, ${data.image.base64}`}/>}
        <input type={`checkbox`} onChange={_ => setPurple(!purple)} />
    </div>
)

所有这些也都工作正常,除了一旦单击复选框,旧图像就会消失并且我得到loading.gif直到获取新图像。 这并不出乎意料,但却是不受欢迎的。 我宁愿保留旧图像并在新图像到达后设置它。

我尝试将旧图像的 base64 字符串写入useState挂钩并从那里读取它,直到它被新图像替换为止。 那行得通,但我的印象是表现不佳。 (站点上有很多很多这样的组件,当用户滚动足够长的时间时,可能会加载数百个组件,这会导致 React state 臃肿。这可能是个问题还是我想象的?我可以分析一下吗?)

这让我想到了我的问题:React 中是否有一种方法可以以某种方式推迟完整的重新渲染并在新的 state 生效之前保留旧的 state 一段时间?

好吧,假设您使用的是 Apollo Client,您正在寻找的是previousData钩子结果属性

https://www.apollographql.com/docs/react/data/queries/#previousdata

根据文档

一个 object 包含最近一次执行此查询的结果。

如果这是查询的第一次执行,则此值未定义。

所以类似的东西(通过将image变量与?. (可选链接)你可以避免 boolean 变量来决定是否显示图像)

const { data, loading, error, previousData } = useQuery(/* ... */);
const image = data?.image?.base64 || previousData?.image?.base64;

注意:我建议您更改加载逻辑以仅在加载且未设置image时显示加载微调器,以避免加载微调器和上一个图像一起显示。 如果出现错误,您最终可以隐藏图像。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM