在 React 中使用 View Transition 更新 State

ViewTransition API 是一个新特性,可以快捷地实现平滑的界面转换。document.startViewTransition 接收一个 function 类型的参数 callback,其返回一个 promise。当这个 promiseresolve 时,表示所有 DOM 已修改完成,过渡开始。

Parameters
callback
A callback function typically invoked to update the DOM during the view transition process, which returns a Promise. The callback is invoked once the API has taken a screenshot of the current page. When the promise returned by the callback fulfills, the view transition begins in the next frame. If the promise returned by the callback rejects, the transition is abandoned.

在 React 中,state 的更新不是同步的,这意味着直接在 startViewTransitionsetState (如下代码)是不完全可行的,极端情况下,当 React 更新 DOM 后,ViewTransition 可能已经开始甚至结束了,此时 DOM 变动后的截图也会出现错误。

const [value, setValue] = useState(/* something */);
document.startViewTransition(() => {
    setValue(/* new value*/);
});

我们需要在 React 更新 DOM 之后 resolve 这个 promise,来在正确的时机开始 ViewTransition。在调用 API 时记录 resolve 函数,并在 useLayoutEffectresolve

function useViewTransitionState(initialValue) {
	const [value, setValue] = useState(initialValue);
	const transitionPromiseResolver = useRef(null);

	useLayoutEffect(() => {
		if (transitionPromiseResolver.current) {
			transitionPromiseResolver.current();
			transitionPromiseResolver.current = null;
		}
	}, [value]);

	const _setValue = (newValue) => {
		if (!document.startViewTransition) {
			setValue(newValue);
			return;
		}
		document.startViewTransition(() => {
			setValue(newValue);
			return new Promise((resolve) => {
				transitionPromiseResolver.current = resolve;
			});
		});
	};

	return [value, _setValue];
}
作者: solstice23
本文采用 CC BY-NC-SA 4.0 协议

评论

  1. StarryNight
    Windows Firefox
    3月前
    2023-8-10 17:41:31

    感谢大佬

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: Telegram @AmashiroNatsukiEars_NoWord Sticker
Source: Telegram Animated Emojis
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
AmashiroNatsukiEars
Telegram Emojis
小恐龙
花!
上一篇