We want to hear from you!Take our 2021 Community Survey!

Add-Ons de animação

Nota:

ReactTransitionGroup e ReactCSSTransitionGroup foram movidos para o pacote react-transition-group que é mantido pela comunidade. Sua ramificação 1.x é totalmente compatível com a API com os complementos existentes. Por favor, arquive bugs e solicitações de recursos no novo repositório.

O componente complementar ReactTransitionGroup é uma API low-level para animação, e o ReactCSSTransitionGroup é um componente complementar para implementar facilmente animações e transições CSS básicas.

High-level API: ReactCSSTransitionGroup

ReactCSSTransitionGroup é uma API high-level baseada em ReactTransitionGroup e é uma maneira fácil de realizar transições e animações CSS quando um componente React entra ou sai do DOM. É inspirado na excelente biblioteca ng-animate.

Importando

import ReactCSSTransitionGroup from 'react-transition-group'; // ES6
var ReactCSSTransitionGroup = require('react-transition-group'); // ES5 com npm
class TodoList extends React.Component {
  constructor(props) {
    super(props);
    this.state = {items: ['hello', 'world', 'clique', 'aqui']};
    this.handleAdd = this.handleAdd.bind(this);
  }

  handleAdd() {
    const newItems = this.state.items.concat([
      prompt('Digite algum texto')
    ]);
    this.setState({items: newItems});
  }

  handleRemove(i) {
    let newItems = this.state.items.slice();
    newItems.splice(i, 1);
    this.setState({items: newItems});
  }

  render() {
    const items = this.state.items.map((item, i) => (
      <div key={i} onClick={() => this.handleRemove(i)}>
        {item}
      </div>
    ));

    return (
      <div>
        <button onClick={this.handleAdd}>Adicionar Item</button>
        <ReactCSSTransitionGroup          transitionName="example"          transitionEnterTimeout={500}          transitionLeaveTimeout={300}>          {items}        </ReactCSSTransitionGroup>      </div>
    );
  }
}

Nota:

Você deve fornecer o atributo key para todos os childrens de ReactCSSTransitionGroup, mesmo ao renderizar apenas um único item. É assim que o React determinará quais childrens entraram, saíram ou ficaram.

Neste componente, quando um novo item é adicionado ao ReactCSSTransitionGroup ele obterá a classe CSS example-enter e a classe CSS example-enter-active, adicionadas no próximo tick. Esta é uma convenção baseada na prop transitionName.

Você pode usar essas classes para acionar uma animação ou transição CSS. Por exemplo, tente adicionar este CSS e adicionar um novo item de lista:

.example-enter {
  opacity: 0.01;
}

.example-enter.example-enter-active {
  opacity: 1;
  transition: opacity 500ms ease-in;
}

.example-leave {
  opacity: 1;
}

.example-leave.example-leave-active {
  opacity: 0.01;
  transition: opacity 300ms ease-in;
}

Você notará que as durações da animação precisam ser especificadas tanto no CSS quanto no método de renderização; isso diz ao React quando remover as classes de animação do elemento e — se estiver saindo — quando remover o elemento do DOM.

Animar a montagem inicial

ReactCSSTransitionGroup fornece a prop opcional transitionAppear, para adicionar uma fase de transição extra na montagem inicial do componente. Geralmente, não há fase de transição na montagem inicial, pois o valor padrão de transitionAppear é false. Abaixo está um exemplo em que passamos a prop transitionAppear com o valor true.

render() {
  return (
    <ReactCSSTransitionGroup
      transitionName="example"
      transitionAppear={true}      transitionAppearTimeout={500}      transitionEnter={false}
      transitionLeave={false}>
      <h1>Fading na montagem inicial</h1>
    </ReactCSSTransitionGroup>
  );
}

Durante a montagem inicial, ReactCSSTransitionGroup obterá a classe CSS example-appear e a classe CSS example-appear-active, adicionadas no próximo tick.

.example-appear {
  opacity: 0.01;
}

.example-appear.example-appear-active {
  opacity: 1;
  transition: opacity .5s ease-in;
}

Na montagem inicial, todos os childrens do ReactCSSTransitionGroup irão conter appear mas não enter. No entanto, todos os childrens adicionados posteriormente a um ReactCSSTransitionGroup irão conter enter mas não appear.

Nota:

A prop transitionAppear foi adicionado ao ReactCSSTransitionGroup na versão 0.13. Para manter a compatibilidade com versões anteriores, o valor padrão é definido como false.

No entanto, os valores padrão de transitionEnter e transitionLeave são true, portanto, você deve especificar o transitionEnterTimeout e o transitionLeaveTimeout por padrão. Se você não precisar entrar ou sair de animações, passe transitionEnter={false} ou transitionLeave={false}.

Classes Personalizadas

Também é possível usar nomes de classes personalizadas para cada uma das etapas em suas transições. Em vez de passar uma string para transitionName, você pode passar um objeto contendo os nomes das classes enter e leave, ou um objeto contendo os nomes das classes enter, enter-active, leave-active, e leave. Se apenas as classes enter e leave forem fornecidas, as classes enter-active e leave-active serão determinadas anexando ‘-active’ ao final do nome da classe. Aqui estão dois exemplos usando classes personalizadas:

// ...
<ReactCSSTransitionGroup
  transitionName={ {
    enter: 'enter',
    enterActive: 'enterActive',
    leave: 'leave',
    leaveActive: 'leaveActive',
    appear: 'appear',
    appearActive: 'appearActive'
  } }>
  {item}
</ReactCSSTransitionGroup>

<ReactCSSTransitionGroup
  transitionName={ {
    enter: 'enter',
    leave: 'leave',
    appear: 'appear'
  } }>
  {item2}
</ReactCSSTransitionGroup>
// ...

O grupo de animação deve ser montado para funcionar

Para que ele aplique transições a seus childrens, o ReactCSSTransitionGroup já deve estar montado no DOM ou a prop transitionAppear deve ser definido como true.

O exemplo abaixo não funcionaria, porque o ReactCSSTransitionGroup está sendo montado junto com o novo item, em vez de o novo item ser montado dentro dele. Compare isso com a seção Primeiros passos acima para ver a diferença.

render() {
  const items = this.state.items.map((item, i) => (
    <div key={item} onClick={() => this.handleRemove(i)}>
      <ReactCSSTransitionGroup transitionName="example">        {item}
      </ReactCSSTransitionGroup>    </div>
  ));

  return (
    <div>
      <button onClick={this.handleAdd}>Adicionar Item</button>
      {items}    </div>
  );
}

Animando Um ou Zero itens

No exemplo acima, renderizamos uma lista de itens em ReactCSSTransitionGroup. No entanto, os childrens de ReactCSSTransitionGroup também podem ser um ou zero itens. Isso torna possível animar um único elemento entrando ou saindo. Da mesma forma, você pode animar um novo elemento substituindo o elemento atual. Por exemplo, podemos implementar um carrossel de imagens simples como este:

import ReactCSSTransitionGroup from 'react-transition-group';

function ImageCarousel(props) {
  return (
    <div>
      <ReactCSSTransitionGroup
        transitionName="carousel"
        transitionEnterTimeout={300}
        transitionLeaveTimeout={300}>
        <img src={props.imageSrc} key={props.imageSrc} />      </ReactCSSTransitionGroup>
    </div>
  );
}

Desativando animações

Você pode desativar a animação de animações enter ou leave, se desejar. Por exemplo, às vezes você pode querer uma animação enter e nenhuma animação leave, mas ReactCSSTransitionGroup espera que uma animação seja concluída antes de remover seu nó DOM. Você pode adicionar a prop transitionEnter={false} ou transitionLeave={false} ao ReactCSSTransitionGroup para desativar essas animações.

Nota:

Ao usar o ReactCSSTransitionGroup, não há como seus componentes serem notificados quando uma transição terminar ou executar qualquer lógica mais complexa em torno da animação. Se você deseja um controle mais refinado, pode usar a API ReactTransitionGroup de nível inferior, que fornece os ganchos necessários para fazer transições personalizadas.


Low-level API: ReactTransitionGroup

Importando

import ReactTransitionGroup from 'react-addons-transition-group' // ES6
var ReactTransitionGroup = require('react-addons-transition-group') // ES5 com npm

ReactTransitionGroup é a base para animações. Quando os childrens são adicionados ou removidos declarativamente (como no exemplo acima), métodos especiais de ciclo de vida são chamados neles.

Renderizando um componente diferente

ReactTransitionGroup é renderizado como um span por padrão. Você pode alterar esse comportamento fornecendo uma prop chamada component. Por exemplo, veja como você renderizaria um <ul>:

<ReactTransitionGroup component="ul">  {/* ... */}
</ReactTransitionGroup>

Quaisquer propriedades adicionais definidas pelo usuário se tornarão propriedades do componente renderizado. Por exemplo, veja como você renderizaria um <ul> com classe CSS:

<ReactTransitionGroup component="ul" className="animated-list">  {/* ... */}
</ReactTransitionGroup>

Cada componente DOM que o React pode renderizar está disponível para uso. No entanto, component não precisa ser um componente DOM. Pode ser qualquer componente React que você queira; mesmo aqueles que você mesmo escreveu! Apenas escreva component={List} e seu componente receberá this.props.children.

Renderizando um Single Child

As pessoas costumam usar o ReactTransitionGroup para animar a montagem e desmontagem de um single child, como um painel dobrável. Normalmente, o ReactTransitionGroup envolve todos os seus childrens em um span (ou um component personalizado, conforme descrito acima). Isso ocorre porque qualquer componente React precisa retornar um único elemento raiz, e ReactTransitionGroup não é exceção a essa regra.

No entanto, se você precisar renderizar apenas um single child dentro do ReactTransitionGroup, poderá evitar completamente envolvê-lo em um <span> ou qualquer outro componente DOM. Para fazer isso, crie um componente personalizado que renderize o primeiro child passado a ele diretamente:

function FirstChild(props) {
  const childrenArray = React.Children.toArray(props.children);
  return childrenArray[0] || null;
}

Agora você pode especificar FirstChild como a prop component nas props do <ReactTransitionGroup> e evitar quaisquer wrappers no DOM resultante:

<ReactTransitionGroup component={FirstChild}>
  {someCondition ? <MyComponent /> : null}
</ReactTransitionGroup>

Isso só funciona quando você está animando um single child dentro e fora, como um painel recolhível. Essa abordagem não funcionaria ao animar vários childrens ou substituir o single child por outro child, como um carrossel de imagens. Para um carrossel de imagens, enquanto a imagem atual está sendo animada, outra imagem será animada, então <ReactTransitionGroup> precisa fornecer a eles um parent DOM comum. Você não pode evitar o wrapper para vários childrens, mas pode personalizar o wrapper com a prop component conforme descrito acima.


Referência

componentWillAppear()

componentWillAppear(callback)

Isso é chamado ao mesmo tempo que componentDidMount() para componentes que são montados inicialmente em um TransitionGroup. Ele bloqueará a ocorrência de outras animações até que a função callback seja chamada. Ele é chamado apenas na renderização inicial de um TransitionGroup.


componentDidAppear()

componentDidAppear()

Isso é chamado depois que a função callback que foi passada para componentWillAppear é chamada.


componentWillEnter()

componentWillEnter(callback)

Isso é chamado ao mesmo tempo que componentDidMount() para componentes adicionados a um TransitionGroup existente. Ele bloqueará a ocorrência de outras animações até que a função callback seja chamada. Ele não será chamado na renderização inicial de um TransitionGroup.


componentDidEnter()

componentDidEnter()

Isso é chamado depois que a função callback que foi passada para componentWillEnter() é chamada.


componentWillLeave()

componentWillLeave(callback)

Isso é chamado quando o child foi removido do ReactTransitionGroup. Embora o child tenha sido removido, o ReactTransitionGroup o manterá no DOM até que a função callback seja chamada.


componentDidLeave()

componentDidLeave()

Isso é chamado quando a função callback de willLeave for chamada (ao mesmo tempo que componentWillUnmount()).

Esta página é útil?Edite esta página