Algo tão simples deve ser facilmente realizado, mas estou puxando meu cabelo por causa do quão complicado é.
Tudo que eu quero fazer é animar a montagem e desmontagem de um componente React, é isso. Aqui está o que tentei até agora e por que cada solução não funciona:
ReactCSSTransitionGroup
- Não estou usando classes CSS, são todos estilos JS, então isso não funcionará.ReactTransitionGroup
- Esta API de nível inferior é ótima, mas requer que você use um retorno de chamada quando a animação estiver concluída, então apenas usar transições CSS não funcionará aqui. Sempre existem bibliotecas de animação, o que nos leva ao próximo ponto:- GreenSock - O licenciamento é muito restritivo para uso comercial IMO.
- React Motion - Parece ótimo, mas
TransitionMotion
é extremamente confuso e complicado demais para o que preciso. - Claro que posso fazer truques como o Material UI faz, em que os elementos são renderizados, mas permanecem ocultos (
left: -10000px
), mas prefiro não seguir esse caminho. Eu considero isso hacky e quero que meus componentes sejam desmontados para que sejam limpos e não atrapalhem o DOM.
Eu quero algo que seja fácil de implementar. Na montagem, anime um conjunto de estilos; ao desmontar, anime o mesmo (ou outro) conjunto de estilos. Feito. Também deve ser de alto desempenho em várias plataformas.
Eu bati em uma parede de tijolos aqui. Se estiver faltando alguma coisa e houver uma maneira fácil de fazer isso, me avise.
transform: scale
.thing { color: #fff; }
) com estilos JS (const styles = { thing: { color: '#fff' } }
))Respostas:
Isso é um pouco demorado, mas usei todos os eventos e métodos nativos para obter essa animação. Não
ReactCSSTransitionGroup
,ReactTransitionGroup
e etc.Coisas que eu usei
onTransitionEnd
eventoComo isso funciona
mounted
) e com o estilo padrão (opacity: 0
)componentDidMount
(componentWillReceiveProps
para atualizações posteriores) para alterar o estilo (opacity: 1
) com um tempo limite (para torná-lo assíncrono).opacity: 0
)onTransitionEnd
, remova desmontar o elemento do DOM.Continue o ciclo.
Percorra o código, você entenderá. Se precisar de algum esclarecimento, por favor deixe um comentário.
Espero que isto ajude.
fonte
onTransitionEnd
? Não vejo isso nos documentos do React.componentWillReceiveProps
pode devolver algo? Onde posso ler mais sobre isso?Parent
componente, você faz referência athis.transitionEnd
Usando o conhecimento adquirido com a resposta de Pranesh, eu vim com uma solução alternativa que é configurável e reutilizável:
Uso:
E finalmente, no
render
método de outro componente :fonte
componentWillLeave()
e écomponentWillEnter()
chamadoAnimatedMount
?Aqui está minha solução usando a nova API de ganchos (com TypeScript), baseada neste post , para atrasar a fase de desmontagem do componente:
Uso:
Link CodeSandbox .
fonte
Eu me opus a esse problema durante meu trabalho e, por mais simples que pareça, realmente não está no React. Em um cenário normal em que você renderiza algo como:
conforme as
this.state.show
alterações, os filhos são montados / desmontados imediatamente.Uma abordagem que
Animate
usei foi criar um componente wrapper e usá-lo comoagora, como
this.state.show
mudanças, podemos perceber mudanças de objetosgetDerivedStateFromProps(componentWillReceiveProps)
e criar estágios intermediários de renderização para realizar animações.Começamos com o Estágio Estático quando os filhos são montados ou desmontados.
Depois de detectar as
show
mudanças de sinalizador, entramos no estágio de preparação, onde calculamos as propriedades necessárias comoheight
ewidth
deReactDOM.findDOMNode.getBoundingClientRect()
.Em seguida, entrando no Animate State , podemos usar a transição css para alterar a altura, largura e opacidade de 0 para os valores calculados (ou para 0 se desmontar).
No final da transição, usamos
onTransitionEnd
api para voltar aoStatic
palco.Há muito mais detalhes sobre como os estágios são transferidos sem problemas, mas essa pode ser uma ideia geral :)
Se alguém estiver interessado, criei uma biblioteca React https://github.com/MingruiZhang/react-animate-mount para compartilhar minha solução. Qualquer feedback é bem-vindo :)
fonte
Acho que usar
Transition
doreact-transition-group
é provavelmente a maneira mais fácil de rastrear a montagem / desmontagem. É incrivelmente flexível. Estou usando algumas classes para mostrar como é fácil de usar, mas você pode definitivamente ligar suas próprias animações JS utilizandoaddEndListener
prop - com o qual tive muita sorte usando GSAP também.Sandbox: https://codesandbox.io/s/k9xl9mkx2o
E aqui está meu código.
fonte
show
propriedadeH1
e fazer toda a lógica dentro do componente estilizado. Como ...animation: ${({ show }) => show ? entranceKeyframes : exitKeyframes} 300ms ease-out forwards;
Movimento Framer
Instale o framer-motion do npm.
fonte
Para aqueles que estão considerando o movimento de reação, animar um único componente quando ele é montado e desmontado pode ser difícil de configurar.
Existe uma biblioteca chamada react-motion-ui-pack que torna este processo muito mais fácil de começar. É um invólucro em torno do movimento de reação, o que significa que você obtém todos os benefícios da biblioteca (ou seja, você pode interromper a animação, ter várias desmontagens ao mesmo tempo).
Uso:
Enter define qual deve ser o estado final do componente; deixar é o estilo aplicado quando o componente é desmontado.
Você pode descobrir que, depois de usar o pacote de interface do usuário algumas vezes, a biblioteca de reação-movimento pode não ser mais tão assustadora.
fonte
Animar as transições de entrada e saída é muito mais fácil com o react-move .
exemplo em codesandbox
fonte
Isso pode ser feito facilmente usando o
CSSTransition
componente dereact-transition-group
, que é igual às bibliotecas que você mencionou. O truque é que você precisa envolver o componente CSSTransition sem um mecanismo mostrar / ocultar como você normalmente faria.{show && <Child>}...
Ou seja, você está ocultando a animação e ela não funcionará. Exemplo:fonte
Aqui estão meus 2 centavos: obrigado a @deckele pela solução. Minha solução é baseada na dele, é a versão do componente stateful, totalmente reutilizável.
aqui minha sandbox: https://codesandbox.io/s/302mkm1m .
aqui meu snippet.js:
fonte
Veja como eu resolvi isso em 2019, enquanto fazia um botão giratório de carregamento. Estou usando componentes funcionais do React.
Eu tenho um componente de aplicativo pai que possui um componente Spinner filho .
O aplicativo determina se o aplicativo está carregando ou não. Quando o aplicativo está carregando, Spinner é renderizado normalmente. Quando o aplicativo não está carregando (
isLoading
é falso), o Spinner é renderizado com o propshouldUnmount
.App.js :
O Spinner define se está oculto ou não. No início, com adereços e estado padrão, Spinner é renderizado normalmente. A
Spinner-fadeIn
classe o anima com o esmaecimento. Quando o Spinner recebe o adereço,shouldUnmount
ele renderiza com aSpinner-fadeOut
classe, animando-o com o esmaecimento.No entanto, eu também queria que o componente desmontasse depois de desaparecer.
Neste ponto, tentei usar o
onAnimationEnd
evento sintético React, semelhante à solução de @pranesh-ravi acima, mas não funcionou. Em vez disso, costumavasetTimeout
definir o estado como oculto com um atraso da mesma duração da animação. O Spinner será atualizado após o atraso comisHidden === true
e nada será renderizado.A chave aqui é que o pai não desmonta o filho, ele diz ao filho quando desmontar e o filho desmonta a si mesmo depois de cuidar de seus negócios de desmontagem.
Spinner.js :
Spinner.css:
fonte
Eu também precisava urgentemente de animação de um único componente. Eu cansei de usar React Motion, mas estava puxando meus cabelos por um assunto tão trivial .. (coisa que eu). Depois de pesquisar no Google, encontrei este post no repositório git deles. Espero que ajude alguém ..
Referenciado de e também o crédito . Isso funciona para mim a partir de agora. Meu caso de uso foi um modal para animar e desmontar no caso de carregar e descarregar.
fonte
Eu sei que há muitas respostas aqui, mas ainda não encontrei uma que se adequasse às minhas necessidades. Eu quero:
Depois de muitas horas mexendo, eu tenho uma solução que funciona, diria 90%. Eu escrevi a limitação em um bloco de comentário no código abaixo. Eu ainda adoraria uma solução melhor, mas esta é a melhor que encontrei, incluindo as outras soluções aqui.
Se você tem um componente que deseja fade in / out, envolva-o em
<Fade>
Ex.<Fade><MyComponent/><Fade>
.Observe que isso é usado
react-bootstrap
para os nomes das classes e para<Container/>
, mas ambos podem ser facilmente substituídos por CSS personalizado e um antigo regular<div>
.fonte
Se eu usar
Velocity
ou aAnimeJS
biblioteca para animar o nó diretamente (em vez decss
ousetTimeout
), descobri que posso criar umhook
para fornecer o status da animaçãoon
e a funçãoonToggle
para iniciar a animação (por exemplo, slidedown, fade).Basicamente, o que o gancho faz é ligar e desligar a animação e depois atualizá-la de
on
acordo. Portanto, podemos obter o status da animação com precisão. Sem fazer isso, responderia em um ad-hocduration
.O uso é o seguinte,
e a implementação animada pode ser,
fonte
Você pode usar o React SyntheticEvent para isso.
Com eventos como onAnimationEnd ou onTransitionEnd, você pode fazer isso.
React Docs: https://reactjs.org/docs/events.html#animation-events
Exemplo de código: https://dev.to/michalczaplinski/super-easy-react-mount-unmount-animations-with-hooks-4foj
fonte