Day21-React 简易动画篇-下篇

这篇要继续介绍剩下的两个元件。

SwitchTransition 元件

主要是用来渲染两个状态间做切换的过渡动画,假如想要让新元素加入和旧元素移除同时发生时出现动画,官方网站比较建议使用 TransitionGroup 元件。

SwitchTransition 元件有 props 属性 mode,当值为:

  • in-out:等待新元素先加入,再等待旧元素移除
  • out-in:等待旧元素先移除,再加入新元素

在使用 SwitchTransition 元件时,里面要有 CSSTransition 或者 Transition 元件,并且里面的这两种元件是透过 key 属性去判断状态,而不是 in。

以下是官方提供的使用 SwitchTransition 元件的范例,不过只有片段的程序,透过阅读可以看到 CSSTransition 用 key 去取得 state,并且被 SwitchTransition 元件包覆。

function App() {
 const [state, setState] = useState(false);
 return (
   <SwitchTransition>
     <CSSTransition
       key={state ? "Goodbye, world!" : "Hello, world!"}
       addEndListener={(node, done) => node.addEventListener("transitionend", done, false)}
       classNames='fade'
     >
       <button onClick={() => setState(state => !state)}>
         {state ? "Goodbye, world!" : "Hello, world!"}
       </button>
     </CSSTransition>
   </SwitchTransition>
 );
}
.fade-enter{
   opacity: 0;
}
.fade-exit{
   opacity: 1;
}
.fade-enter-active{
   opacity: 1;
}
.fade-exit-active{
   opacity: 0;
}
.fade-enter-active,
.fade-exit-active{
   transition: opacity 500ms;
}

完整的范例在这个连结:

官方范例连结

接着我们来做一个范例,每次转换状态 state 时都会出现不同的色块:

程序码范例

TransitionGroup 元件

用来管理多个 transition 元件,包括 <Transition><CSSTransition>,将这些元件包覆後 in 这个属性就由 TransitionGroup 管理,每个内部的 transition 元件都可以设计自己的动画。

以下是官方范例,点击删除按钮时,列表中的某个项目会被删除,项目对应到的 in 属性会被自动改为 false,触发离场动画。

function TodoList() {
  const [items, setItems] = useState([
    { id: uuid(), text: 'Buy eggs' },
    { id: uuid(), text: 'Pay bills' },
    { id: uuid(), text: 'Invite friends over' },
    { id: uuid(), text: 'Fix the TV' },
  ]);
  return (
    <Container style={{ marginTop: '2rem' }}>
      <ListGroup style={{ marginBottom: '1rem' }}>
        <TransitionGroup className="todo-list">
          {items.map(({ id, text }) => (
            <CSSTransition
              key={id}
              timeout={500}
              classNames="item"
            >
              <ListGroup.Item>
                <Button
                  className="remove-btn"
                  variant="danger"
                  size="sm"
                  onClick={() =>
                    setItems(items =>
                      items.filter(item => item.id !== id)
                    )
                  }
                >
                  &times;
                </Button>
                {text}
              </ListGroup.Item>
            </CSSTransition>
          ))}
        </TransitionGroup>
      </ListGroup>
      <Button
        onClick={() => {
          const text = prompt('Enter some text');
          if (text) {
            setItems(items => [
              ...items,
              { id: uuid(), text },
            ]);
          }
        }}
      >
        Add Item
      </Button>
    </Container>
  );
}

范例连结

React Transition Group 搭配 react router

最後,React Transition Group 也可以搭配 react router 一起使用,可参考以下连结:

范例


<<:  网页表单-30天学会HTML+CSS,制作精美网站

>>:  Builder 建造者模式

前言与介绍

前言 大家好,我是赖沅承,是一名来自台北市立南港高级中学的学生,我从高中开始加入了数位科学实验班,才...

[DAY14]地图与组图(1)

LocationSendMessage location_message = LocationSen...

Day10 - 套用 Tag Helper - 复杂型别 object

这篇开始使用 Tag Helper 来 Render 出需要的 Html 控制项 name,方便在 ...

用React刻自己的投资Dashboard Day2 - 网站Wireframe设计

tags: 2021铁人赛 React 投资Dashboard内容设计 要实际动手制作wirefra...

[Angular] Day16. Writing structural directives

在上一章中介绍了如何建立客制化的 attribute directive 与使用,而本章将会介绍如何...