同時モード对 ユーザー使用可能造成的影响
4813 ワード
需要的前置知识:
Concurrent mode
在 同時実行モード最后一次 レンダリング不代表集約最新的 コミット状态」
有最新 州・支柱的优先级较低的 レンダリング可能会重写当前 イベントハンドラ使用的 リファレンス useRef React strict mode
React render phase & commit phase useEffect : timing of effect 我在这个 issue 的讨论里面看到了关于未来 同時モード对
这个回答还是有点简略,不太好懂,我再扩展一下
比如这个 デモ:https://codesandbox.io/s/useref-strict-mode-3xpf3?file=/src/App.tsx
可以对比一下例子里面的两个组件
バッドカウンター.TSX
但是我通过把它包在
进行了两次 レンダリング但是只 コミット了一次,所以点按钮重渲染之后会增加 2
グッドカウンター.TSX
useEffect 里面的函数只会在 commit phase 去调用
所以就算 レンダリングフェーズ:コミットフェーズ不再是 1 : 1也可以集約展示想要的状态」
别人写的使用 同時モード的相同 デモ:https://codesandbox.io/s/x2p46v02z4
也是一样的道理
所以未来如果要升级到 同時モード的版本
对于
我能想到的对于升级到 同時モード的 ベストプラクティス 可以通过
因为考虑到会出现的危险,尽量少用 参考资料 How To Properly Use the React useRef Hook in Concurrent Mode React lifecycle methods diagram [Hooks] Alternative useCallback implementation
Concurrent mode
在 同時実行モード最后一次 レンダリング不代表集約最新的 コミット状态」
有最新 州・支柱的优先级较低的 レンダリング可能会重写当前 イベントハンドラ使用的 リファレンス
React render phase & commit phase
useRef
使用可能造成的影响Q: What issues has "mutation of ref during rendering"? Can you explain me in brief?
A: In concurrent mode (not yet released), it would "remember" the last rendered version, which isn't great if we render different work-in-progress priorities. So it's not "async safe".
这个回答还是有点简略,不太好懂,我再扩展一下
useRef
的功能相当于是一个全局变量,所以改变它其实是会造成副作用的比如这个 デモ:https://codesandbox.io/s/useref-strict-mode-3xpf3?file=/src/App.tsx
可以对比一下例子里面的两个组件
バッドカウンター.TSX
const BadCounter = () => {
const count = useRef(0);
count.current += 1;
return (
<div className="counter">
BAD COUNTER <br /> count:{count.current}
</div>
);
};
显然这在现在非 同時モード的情景下可以正常工作,因为现在 render 阶段(计算组件哪里需要更新,即调用 render 函数 比较本次和之前的计算结果)和 commit 阶段(把计算出来的变化CRUD到 DOM 里) 是一比一的但是我通过把它包在
<StrictMode/>
里面利用 厳格モード触发了两次 機能コンポーネント本体中的内容进行了两次 レンダリング但是只 コミット了一次,所以点按钮重渲染之后会增加 2
グッドカウンター.TSX
import React, { useEffect, useRef } from "react";
const GoodCounter = () => {
const count = useRef(0);
let currentCount = count.current;
useEffect(() => {
count.current = currentCount;
});
currentCount += 1;
return (
<div className="counter">
GOOD COUNTER <br /> count:{currentCount}
</div>
);
};
export default GoodCounter;
改进后的组件把对 ref的修改放进了 useEffect
中useEffect 里面的函数只会在 commit phase 去调用
所以就算 レンダリングフェーズ:コミットフェーズ不再是 1 : 1也可以集約展示想要的状态」
PS 这里官方对于
useCallback
里面如何读取总是改变的值的 workaround 的例子就是放在useEffect
里面处理的:https://reactjs.org/docs/hooks-faq.html#how-to-read-an-often-changing-value-from-usecallback
别人写的使用 同時モード的相同 デモ:https://codesandbox.io/s/x2p46v02z4
也是一样的道理
所以未来如果要升级到 同時モード的版本
对于
useRef
的使用需要非常小心我能想到的对于升级到 同時モード的 ベストプラクティス
strict mode
先对会产生副作用的函数(包括但不仅限于改变 参考进行一波检查 因为考虑到会出现的危险,尽量少用
~~useRef~~
考虑能否用其他 非同期セーフ的 フック替代(比如上面的例子就可以用 useState
或者 useCallback
替代) Reference
この問題について(同時モード对 ユーザー使用可能造成的影响), 我々は、より多くの情報をここで見つけました https://dev.to/lydiayuan/concurrent-mode-dui-useref-shi-yong-ke-neng-zao-cheng-de-ying-xiang-3831テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol