>  기사  >  웹 프론트엔드  >  React18의 새로운 개념 Transition에 대한 간략한 분석

React18의 새로운 개념 Transition에 대한 간략한 분석

青灯夜游
青灯夜游앞으로
2022-03-25 10:52:462463검색

이 글은 여러분에게 React18의 Transition의 새로운 개념을 이해하도록 안내하고, 새로운 API인 startTransition과 새로운 후크인 useTransition 및 UsedDeferredValue의 사용법을 간략하게 소개합니다. 모든 사람에게 도움이 되기를 바랍니다!

React18의 새로운 개념 Transition에 대한 간략한 분석

React 18에는 새로운 개념인 transition이 도입되어 새로운 API인 startTransition과 두 개의 새로운 후크 ——useTransition를 제공합니다. code> 및 usedeferredValue에 관한 이 문서는 얼리 어답터 소개로 시작됩니다. [관련 권장사항: Redis 동영상 튜토리얼]transition,由此带来了一个新的API——startTransition和两个新的hooks——useTransitionusedeferredValue,本文由此展开使用尝鲜介绍。【相关推荐:Redis视频教程

1. 总览

本文分为4部分进行:

  • tansition 产生初衷
  • startTransition 使用和介绍
  • useTransition 使用和介绍
  • useDeferredValue 使用和介绍

2. transition产生初衷

transtion 直接翻译为 过渡。tansition本质上是为了解决渲染并发问题所提出。在React中一旦组件状态改变并触发了重新渲染,则无法停止渲染。直到组件重新渲染完毕,页面才能继续响应用户的交互。

为此react 18中更新都可以划分为以下两类:

  • 紧急更新(urgent update):用户期望马上响应的更新操作,例如鼠标单击或键盘输入。
  • 过渡更新(transition update):一些延迟可以接受的更新操作,如查询时,搜索推荐、搜索结果的展示等。
// 被startTransiton标记后为过渡更新
startTransition(()=> {
    // 非紧急更新,会被降低优先级,延迟执行
    setQueryValue(inputValue)
})

// 未被标记则马上执行
setInputValue(inputValue)

在react 18中被startTrionstion标记的更新,即为过渡更新(执行的优先级被降低),此时react会根据内部的调度机制延迟执行内部的state更新。

开发中开发者可以通过transition hook决定哪些更新被标记为transition事件。一旦被标记则代表为低优先级执行,即react知道该state可以延迟更新,通过区分更新优先级,让高优先级的事件保持响应,提高用户交互体验,保持页面响应

3. startTransiton

startTransiton使用介绍

const handleClick = () => {
    // startTransition包裹标记为低优先级更新
    startTransition(()=> {
        setQueryValue(inputValue)
    })
    
    // 未被标记则马上执行
    setInputValue(inputValue)
}

首先我们来介绍下最简单的startTransition

  • startTransiton 是一个接受回调的函数,用于告知React需要延迟更新的state。
  • 如果某个state的更新会导致组件挂起,则应该包裹在startTransition中

通过演示对比

这是一个对输入字符后展示搜索结果的场景模拟,通过伪造大量搜索结果,模拟容易卡顿的情况。

我们试着连续输入123,监听搜索框值value变化(urgent update)和搜索值searchVal变化(transition update)并输出到控制栏。

import React, { useEffect, useState, startTransition } from 'react';
import './App.css'

const SearchResult = (props) => {
    const resultList = props.query
        ? Array.from({ length: 10000 }, (_, index) => ({
            id: index,
            keyword: `${props.query} -- 搜索结果${index}`,
        })) : [];
    return resultList.map(({ id, keyword }) => (
        <li key={id}>{keyword}</li>
    ))
}

const App = () => {
    const [type, setTpye] = useState(1)
    const [value, setValue] = useState(&#39;&#39;);
    const [searchVal, setSearchVal] = useState(&#39;-&#39;);

    useEffect(() => {
        // 监听搜索值改变
        console.log(&#39;对搜索值更新的响应++++++&#39; + searchVal + &#39;+++++++++++&#39;)
    }, [searchVal])

    useEffect(() => {
        console.log(&#39;对输入框值更新的响应-----&#39; + value + &#39;-------------&#39;)
        if (type === 1) {
            setSearchVal(value || &#39;-&#39;)
        }
        if (type === 2) {
            startTransition(() => {
                setSearchVal(value || &#39;-&#39;)
            })
       }
    }, [value, type]);

    return (
        <div className=&#39;App&#39;>
            <input value={value} onChange={e => setValue(e.target.value)} />
            <div className={`type_button ${type === 1 ? &#39;type_button_checked&#39; : &#39;&#39;}`} onClick={() => setTpye(1)}>normal</div>
            <div className={`type_button ${type === 2 ? &#39;type_button_checked&#39; : &#39;&#39;}`} onClick={() => setTpye(2)}>transiton</div>
            <ul>
                <SearchResult query={searchVal}></SearchResult>
            </ul>
        </div>
    );
};

普通模式下

React18의 새로운 개념 Transition에 대한 간략한 분석

如图所示:连续输入字符123,当第一个字符输入后,搜索值马上响应,列表渲染立刻开始,造成卡顿输入框停止了对用户输入的响应,直到渲染结束,输入框才继续响应。

使用startTransition后

React18의 새로운 개념 Transition에 대한 간략한 분석

如图所示:连续输入字符123,输入框不断响应,搜索值的响应被延后,保证页面反馈,直到输入结束,才开始响应搜索值,渲染搜索结果,保持页面响应。

4. useTransiton

useTransiton使用介绍

import { useTransiton } from &#39;react&#39;

const [isPending, startTransition] = useTransiton({timeoutMs: 2000})
// 例如, 在pending状态下,您可以展示一个Spinner
{ isPending ? < Spinner /> : null }
  • startTransition 是一个接受回调的函数,用于告知React需要延迟更新的state。
  • isPending 是一个布尔值,这是react告知我们是否等待过渡完成的方式。
  • useTransition 接受带有 timeoutMs 的延迟响应的值,如果给定的timeoutMs内未完成,它将会强制执行startTransition回调函数内state的更新。

useTransiton简单分析

我们通过伪代码理解下useTransition

1. 개요🎜🎜이 문서는 4개 부분으로 구성되어 있습니다: 🎜
  • tansition 원래 의도
  • startTransition 사용법 및 소개
  • useTransition 사용법 및 소개
  • useDeferredValue 사용법 및 소개
🎜2. 전환의 원래 의도🎜🎜전환 전환을 직접 번역합니다. Tansition은 본질적으로 렌더링 동시성 문제를 해결하기 위해 제안됩니다. React에서는 구성 요소 상태가 변경되고 다시 렌더링이 트리거되면 렌더링을 중지할 수 없습니다. 페이지는 구성 요소가 다시 렌더링될 때까지 사용자 상호 작용에 계속 응답할 수 없습니다. 🎜🎜이러한 이유로 React 18의 업데이트는 다음 두 가지 범주로 나눌 수 있습니다: 🎜
  • 긴급 업데이트(긴급 업데이트): 사용자가 즉시 응답할 것으로 기대하는 업데이트 작업 마우스 클릭이나 키보드 입력 등.
  • 전환 업데이트(전환 업데이트): 쿼리 시간, 추천 검색어, 검색 결과 표시 등과 같이 허용 가능한 지연이 있는 일부 업데이트 작업입니다.
function useTransition(){
    const [isPending, setPending] = mountState(false);
    const start = (callback)=>{
        setPending(true);
        // Scheduler.unstable_next 通过 transiton 模式,低优先级调度执行回调函数
        // 可以降低更新的优先级。如果回调中触发的更新优先级会比较低,
        // 它会让位为高优先级的更新,或者当前事务繁忙时,调度到下一空闲期再应用。
        Scheduler.unstable_next(() => {
            const prevTransition = ReactCurrentBatchConfig.transition;
            ReactCurrentBatchConfig.transition = 1;
            try {
                setPending(false);
                //实行回调函数
                callback();
            } finally {
                ReactCurrentBatchConfig.transition = prevTransition;
            }
        })
    }
    return [isPending, start];
}
🎜react 18에서 startTrionstion으로 표시된 업데이트는 과도기 업데이트입니다(실행 우선순위가 낮아짐). 이때 내부 스케줄에 따라 React가 지연됩니다. 메커니즘 내부 상태 업데이트를 수행합니다. 🎜🎜개발 중인 개발자는 전환 후크를 통해 전환 이벤트로 표시할 업데이트를 결정할 수 있습니다. 일단 표시되면 우선순위가 낮은 실행을 나타냅니다. 즉, React는 업데이트 시 상태가 지연될 수 있다는 것을 알고 있습니다. 업데이트 우선순위를 구별하여 우선순위가 높은 이벤트는 응답 상태를 유지하여 개선됩니다. 사용자 상호 작용 경험을 통해 페이지의 반응성을 유지하세요. 🎜🎜3. startTransiton🎜🎜startTransiton 사용 소개🎜
const [value, setValue] = useState(&#39;&#39;)
// defferedValue值延后于state更新
const deferredValue = useDeferredValue(value, {timeoutMs: 2000})
🎜우선 , 가장 간단한startTransition을 소개하겠습니다🎜
  • startTransiton은 콜백을 받아들이는 함수이며 지연되어야 하는 상태를 React에 알리는 데 사용됩니다.
  • 특정 상태 업데이트로 인해 구성 요소가 중단되는 경우 startTransition으로 래핑해야 합니다.
🎜시연을 통한 비교 🎜🎜문자 입력 후 검색결과가 나오는 시나리오 시뮬레이션입니다. 검색결과를 대량으로 위조하여 멈춤 현상이 발생하기 쉬운 상황을 시뮬레이션한 것입니다. 🎜🎜123을 연속적으로 입력하려고 노력하고, 검색창 값 변경(긴급 업데이트)과 검색 값 searchVal 변경(전환 업데이트)을 모니터링하여 컨트롤바에 출력합니다. . 🎜
import React, { useEffect, useState, useTransition, useDeferredValue } from &#39;react&#39;;
import &#39;./App.css&#39;

const SearchResult = (props) => {
    const resultList = props.query
        ? Array.from({ length: 10000 }, (_, index) => ({
            id: index,
            keyword: `${props.query} -- 搜索结果${index}`,
        })) : [];
    return resultList.map(({ id, keyword }) => (
        <li key={id}>{keyword}</li>
    ))
}

const App = () => {
    const [value, setValue] = useState(&#39;&#39;);
    const searchValue = useDeferredValue(value, { timeoutMs: 2000 });

    useEffect(() => {
        console.log(&#39;对输入框值的响应--------&#39; + value + &#39;---------------&#39;)
    }, [value])

    useEffect(() => {
        // 监听搜索值改变
        console.log(&#39;对搜索值的更新响应++++++&#39; + searchValue + &#39;+++++++++++&#39;)
    }, [searchValue])

    return (
        <div className=&#39;App&#39;>
            <input value={value} onChange={e => setValue(e.target.value)} />
        <div className={`type_button type_button_checked`}>useDeferredValue</div>
        <ul>
            <SearchResult query={searchValue}></SearchResult>
        </ul>
    </div>
    );
};
🎜일반 모드🎜🎜React18의 새로운 개념 Transition에 대한 간략한 분석🎜🎜그림과 같이: 123자를 연속으로 입력합니다. 첫 번째 문자를 입력하면 검색 값이 즉시 응답하고 목록 렌더링이 즉시 시작됩니다. 지연. 입력 상자가 사용자 입력에 대한 응답을 중지하고 렌더링이 끝날 때까지 계속 응답하지 않습니다. 🎜🎜startTransition 사용 후🎜🎜React18의 새로운 개념 Transition에 대한 간략한 분석🎜🎜그림과 같이: 123자를 연속으로 입력하면 입력 상자가 계속 응답하고 검색 값에 대한 응답이 지연되어 페이지 피드백을 보장합니다. 입력이 완료되었습니다. 검색 값에 응답하고, 검색 결과를 렌더링하고, 페이지의 응답성을 유지합니다. 🎜🎜4. useTransiton🎜🎜useTransiton 소개🎜
function useDeferredValue(value){
    const [prevValue, setValue] = updateState(value);
    updateEffect(() => {
        // 在 useEffect 中通过 transition 模式来更新 value 。
        Scheduler.unstable_next(() => {
            const prevTransition = ReactCurrentBatchConfig.transition;
            ReactCurrentBatchConfig.transition = 1;
            try {
                setValue(value);
            } finally {
                ReactCurrentBatchConfig.transition = prevTransition;
            }
         })
    }, [value]);
    return prevValue;
}
  • startTransition은 콜백을 받아들이고 지연되어야 하는 상태를 React에 알리는 데 사용되는 함수입니다.
  • isPending은 부울 값으로, 전환이 완료될 때까지 기다릴지 여부를 알려주는 React의 방식입니다.
  • useTransitiontimeoutMs로 지연된 응답 값을 허용합니다. 지정된 timeoutMs 내에 완료되지 않으면 startTransition이 강제로 실행됩니다. 콜백 함수의 상태를 업데이트합니다.
🎜useTransiton의 간단한 분석🎜🎜우리는 의사 코드를 통해 useTransition을 이해합니다. 🎜
function useTransition(){
    const [isPending, setPending] = mountState(false);
    const start = (callback)=>{
        setPending(true);
        // Scheduler.unstable_next 通过 transiton 模式,低优先级调度执行回调函数
        // 可以降低更新的优先级。如果回调中触发的更新优先级会比较低,
        // 它会让位为高优先级的更新,或者当前事务繁忙时,调度到下一空闲期再应用。
        Scheduler.unstable_next(() => {
            const prevTransition = ReactCurrentBatchConfig.transition;
            ReactCurrentBatchConfig.transition = 1;
            try {
                setPending(false);
                //实行回调函数
                callback();
            } finally {
                ReactCurrentBatchConfig.transition = prevTransition;
            }
        })
    }
    return [isPending, start];
}

startTransition执行过程中,会触发两次setPending ,一次在transition=1之前,一次在之后。startTransition被调用时setPending(true),当startTransition内部的回调函数执行时transiton过渡任务更新setPending(false)。react内部可以根据pending值的变化准确把握等待的过渡时间,并依此判断是否超过了timeoutMs(如果有传入)强制执行更新。

5. useDeferredValue

useDeferredValue使用介绍

const [value, setValue] = useState(&#39;&#39;)
// defferedValue值延后于state更新
const deferredValue = useDeferredValue(value, {timeoutMs: 2000})
  • useDeferredValue 返回一个延迟响应的状态,可以设置最长延迟时间timeoutMs
  • 可以传入可选的timeoutMs,如果给定的timeoutMs内未完成,它将会强制更新。
  • 与useTransition的不同: useTransition是处理一段逻辑,而useDeferred是产生一个新状态

useDeferredValue的使用

import React, { useEffect, useState, useTransition, useDeferredValue } from &#39;react&#39;;
import &#39;./App.css&#39;

const SearchResult = (props) => {
    const resultList = props.query
        ? Array.from({ length: 10000 }, (_, index) => ({
            id: index,
            keyword: `${props.query} -- 搜索结果${index}`,
        })) : [];
    return resultList.map(({ id, keyword }) => (
        <li key={id}>{keyword}</li>
    ))
}

const App = () => {
    const [value, setValue] = useState(&#39;&#39;);
    const searchValue = useDeferredValue(value, { timeoutMs: 2000 });

    useEffect(() => {
        console.log(&#39;对输入框值的响应--------&#39; + value + &#39;---------------&#39;)
    }, [value])

    useEffect(() => {
        // 监听搜索值改变
        console.log(&#39;对搜索值的更新响应++++++&#39; + searchValue + &#39;+++++++++++&#39;)
    }, [searchValue])

    return (
        <div className=&#39;App&#39;>
            <input value={value} onChange={e => setValue(e.target.value)} />
        <div className={`type_button type_button_checked`}>useDeferredValue</div>
        <ul>
            <SearchResult query={searchValue}></SearchResult>
        </ul>
    </div>
    );
};

React18의 새로운 개념 Transition에 대한 간략한 분석

useDeferredValue简单分析

我们通过伪代码理解下useDeferredValue

function useDeferredValue(value){
    const [prevValue, setValue] = updateState(value);
    updateEffect(() => {
        // 在 useEffect 中通过 transition 模式来更新 value 。
        Scheduler.unstable_next(() => {
            const prevTransition = ReactCurrentBatchConfig.transition;
            ReactCurrentBatchConfig.transition = 1;
            try {
                setValue(value);
            } finally {
                ReactCurrentBatchConfig.transition = prevTransition;
            }
         })
    }, [value]);
    return prevValue;
}

useDeferredValue通过useEffect监听传入值的变化,然后通过过渡任务执行值的改变。这样保证defrredValue的更新滞后于setState,同时符合过渡更新的原则,因为是通过transition 调度机制执行的。

更多编程相关知识,请访问:编程视频!!

위 내용은 React18의 새로운 개념 Transition에 대한 간략한 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 juejin.cn에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제