Como começar rapidamente com o VUE3.0: Ao entrar para aprender
o React 18, um novo conceito - transition
é introduzido, que traz uma nova API - startTransition
e dois novos ganchos - useTransition
e usedeferredValue
Este artigo começa aqui Use as introduções dos primeiros usuários.
1. Visão geral
Este artigo está dividido em quatro partes:
tansition
,startTransition
useTransition
,useDeferredValue
2. A intenção original de transição,
transtion
é traduzida diretamente como过渡
. a transição é essencialmente为了解决渲染并发问题所提出
. No React, uma vez que o estado do componente muda e uma nova renderização é acionada, a renderização não pode ser interrompida. A página não pode continuar respondendo à interação do usuário até que o componente seja renderizado novamente.
Por esse motivo, as atualizações no react 18 podem ser divididas nas duas categorias a seguir:
紧急更新
: operações de atualização que os usuários esperam que respondam imediatamente, como cliques do mouse ou entrada do teclado.过渡更新
: algumas operações de atualização com atraso aceitável, como consulta, recomendação de pesquisa, exibição de resultados de pesquisa, etc.//Atualiza startTransition(()=> { após ser marcado por startTransiton para transição // Atualizações não urgentes terão prioridade reduzida e a execução de setQueryValue(inputValue) será atrasada. }) // Se não estiver marcado, setInputValue(inputValue) será executado imediatamente.
A atualização marcada por startTrionstion
no react 18 é uma atualização transicional (a prioridade de execução é reduzida). atualizar de acordo com o mecanismo de agendamento interno.
Os desenvolvedores em desenvolvimento podem decidir quais atualizações serão marcadas como eventos de transição por meio de ganchos de transição. Uma vez marcado, representa uma execução de baixa prioridade, ou seja, o React sabe que o estado pode atrasar a atualização.通过区分更新优先级
, os eventos de alta prioridade podem permanecer responsivos,提高用户交互体验,保持页面响应
.
3. startTransiton
startTransiton introdução ao uso
const handleClick = () => { // pacote startTransition marcado como atualização de baixa prioridade startTransition(()=> { setQueryValue(inputValue) }) // Se não estiver marcado, setInputValue(inputValue) será executado imediatamente }
Primeiro, vamos apresentar o startTransition mais simples.
Através de demonstração e comparação,
esta é uma simulação de cenário de exibição de resultados de pesquisa após inserir um grande número de resultados de pesquisa, simulando uma situação. que é propenso a congelar.
Tentamos inserir continuamente 123, monitorar a alteração do value
da caixa de pesquisa (atualização urgente) e a alteração do valor de pesquisa searchVal
(atualização de transição) e enviá-lo para a barra de controle.
importar React, { useEffect, useState, startTransition } de 'react'; importar './App.css' const SearchResult = (adereços) => { const listaresultados = props.query ?Array.from({ comprimento: 10000 }, (_, índice) => ({ id: índice, palavra-chave: `${props.query} -- resultados da pesquisa${index}`, })): []; retornar listaderesultados.map(({ id, palavra-chave }) => ( <li key={id}>{palavra-chave}</li> )) } aplicativo const = () => { const [tipo, setTpye] = useState(1) const [valor, setValue] = useState(''); const [searchVal, setSearchVal] = useState('-'); useEffect(() => { // Monitora alterações no valor de pesquisa console.log('Resposta à atualização do valor de pesquisa++++++' + searchVal + '++++++++++++') }, [valorpesquisa]) useEffect(() => { console.log('Resposta à atualização do valor da caixa de entrada-----' + valor + '-------------') se (tipo === 1) { setSearchVal(valor || '-') } se (tipo === 2) { startTransition(() => { setSearchVal(valor || '-') }) } }, [valor, tipo]); retornar ( <div className='Aplicativo'> <valor de entrada={valor} onChange={e => setValue(e.target.value)} /> <div className={`type_button ${type === 1 ? 'type_button_checked' : ''}`} onClick={() => setTpye(1)}>normal</div> <div className={`type_button ${type === 2 ? 'type_button_checked' : ''}`} onClick={() => setTpye(2)}>transição</div> <ul> <consultaSearchResult={searchVal}></SearchResult> </ul> </div> ); };
No modo normal
如图所示:
123 caracteres são inseridos continuamente Quando o primeiro caractere é inserido, o valor de pesquisa responde imediatamente e a renderização da lista começa imediatamente, fazendo com que a caixa de entrada congele e pare de responder à entrada do usuário. continue a responder até que a renderização seja concluída.
Depois de usar startTransition
如图所示:
Inserindo continuamente os caracteres 123, a caixa de entrada continua a responder e a resposta ao valor de pesquisa é atrasada para garantir que o feedback da página não comece a responder ao valor de pesquisa até o final da entrada, renderizando o. resultados de pesquisa e manter a página responsiva.
4. useTransiton
useTransiton introdução de uso
import { useTransiton } from 'react' const [isPending, startTransition] = useTransiton({timeoutMs: 2000}) // Por exemplo, no estado pendente, você pode exibir um Spinner { isPending ? < Spinner /> : null }
startTransition
é uma função que aceita um retorno de chamada e é usada para informar ao React o estado que precisa ser atrasado.isPending
é um booleano, que é a maneira do react nos dizer se devemos esperar a conclusão da transição.useTransition
aceita o valor de uma resposta atrasada com timeoutMs
. Se não for concluído dentro do timeoutMs fornecido, forçará a atualização do estado na função de retorno de chamada startTransition
.Análise simples de useTransiton
Entendemos useTransition
por meio de pseudocódigo.
função useTransição(){ const [isPending, setPending] = mountState(false); const início = (retorno de chamada)=>{ setPending(verdadeiro); // Scheduler.unstable_next Através do modo de transição, a função de retorno de chamada de execução de agendamento de baixa prioridade // pode reduzir a prioridade das atualizações. Se a atualização acionada no retorno de chamada tiver prioridade mais baixa, // Será definido para uma atualização de alta prioridade, ou quando a transação atual estiver ocupada, será agendado para ser aplicado no próximo período ocioso. Agendador.unstable_next(() => { const prevTransition = ReactCurrentBatchConfig.transition; ReactCurrentBatchConfig.transition = 1; tentar { setPendente(falso); //Executa a função de retorno de chamada callback(); } finalmente { ReactCurrentBatchConfig.transition = prevTransition; } }) } return [isPendente, início]; }
Durante a execução de startTransition
, setPending será acionado duas vezes, uma antes de transition=1
e outra depois. setPending(true)
quando startTransition
é chamado e transiton
atualiza setPending(false)
quando a função de retorno de chamada dentro de startTransition
é executada. O React pode compreender com precisão o tempo de transição de espera com base nas alterações no valor pendente e usar isso para determinar se timeoutMs
foram excedidos (se algum for passado) para forçar uma atualização.
5. useDeferredValue
useDeferredValue introdução ao uso
const [value, setValue] = useState('') // O valor defferedValue é atrasado após a atualização do estado const deferredValue = useDeferredValue(value, {timeoutMs: 2000})
timeoutMs
pode ser definido.一段逻辑
, enquanto useDeferred gera一个新状态
.Uso de useDeferredValue
import React, { useEffect, useState, useTransition, useDeferredValue } from 'react'; importar './App.css' const SearchResult = (adereços) => { const listaresultados = props.query ?Array.from({ comprimento: 10000 }, (_, índice) => ({ id: índice, palavra-chave: `${props.query} -- resultados da pesquisa${index}`, })): []; retornar listaderesultados.map(({ id, palavra-chave }) => ( <li key={id}>{palavra-chave}</li> )) } aplicativo const = () => { const [valor, setValue] = useState(''); const searchValue = useDeferredValue(valor, {timeoutMs: 2000 }); useEffect(() => { console.log('Resposta ao valor da caixa de entrada --------' + valor + '---------------') }, [valor]) useEffect(() => { // Monitora alterações no valor de pesquisa console.log('Atualizar resposta para valor de pesquisa++++++' + searchValue + '++++++++++++') }, [valorpesquisa]) retornar ( <div className='Aplicativo'> <valor de entrada={valor} onChange={e => setValue(e.target.value)} /> <div className={`type_button type_button_checked`}>useDeferredValue</div> <ul> <ConsultaSearchResult={searchValue}></SearchResult> </ul> </div> ); };
Análise simples de useDeferredValue
Entendemos useDeferredValue
por meio de pseudocódigo.
função useDeferredValue(valor){ const [prevValue, setValue] = updateState(valor); updateEffect(() => { //Atualiza o valor através do modo de transição em useEffect. Agendador.unstable_next(() => { const prevTransition = ReactCurrentBatchConfig.transition; ReactCurrentBatchConfig.transition = 1; tentar { setValor(valor); } finalmente { ReactCurrentBatchConfig.transition = prevTransition; } }) }, [valor]); return valoranterior; }
useDeferredValue
escuta alterações no valor recebido por meio de useEffect e, em seguida, executa a alteração de valor por meio da tarefa de transição. Isso保证defrredValue的更新滞后于setState
e esteja em conformidade com o princípio da atualização transicional porque é executada por meio do mecanismo de agendamento de transição.