導語
新的一年,換了新的工作也算是新的開始吧,最近對頁面的切換動畫比較感興趣,所以就以React Transition Group庫爲切入口做一些深入的理解吧。
安裝
# npm
npm install react-transition-group --save
# yarn
yarn add react-transition-group
官方提供三個組件,分別爲 Transition, CSSTransition, TransitonGroup。
這一章主要介紹下 Transition 組件。
Transition
Transition 組件允許您使用簡單的聲明性API描述從一個組件狀態到另一個組件狀態的轉換。最常見的是,它用於動畫組件的安裝和卸載,但也可以用於描述就地的過渡狀態。
默認情況下,轉換組件不改變它呈現的組件的行爲,它只跟蹤組件的“進入”和“退出”狀態。由你來賦予這些狀態意義和效果。例如,我們可以在組件進入或退出時向其添加樣式。
如前所述,轉換組件本身不會對其子組件執行任何操作。它所做的是隨時間跟蹤轉換狀態,以便在組件更改狀態時更新組件(例如通過添加樣式或類)。
在一個過渡中有四種主要狀態:
- entering
- entered
- exiting
- exited
過渡狀態通過in屬性切換。當爲true時,組件開始“Enter”階段。在此階段中,組件將從當前轉換狀態轉移到轉換期間的“進入”狀態,然後在完成轉換後再轉移到“進入”狀態。
看完了基本介紹,下面來一個最基本的例子:
首先,創建我們的 Fade 組件
第一步:定義屬性
const duration = 300;
const defaultStyle = {
transition: `opacity ${duration}ms ease-in-out`,
opacity: 0,
}
const transitionStyles = {
entering: { opacity: 0 },
entered: { opacity: 1 },
}
第二步:定義組件
const Fade = (props) => (
<Transition in={props.inProp} timeout={duration}>
{(state) => (
<div style={{
...defaultStyle,
...transitionStyles[state]
}}>
{props.children}
</div>
)}
</Transition>
)
Transition 組件的 in 屬性是一個 boolean 值,由子組件傳入,用於控制子組件的狀態,是否顯示。
我們的 Fade 組件創建好了,接下來就該試試好不好用了,我們創建一個新的組件,定義一些簡單的樣式,定義一個內部狀態show,傳入Fade 組件,然後使用 Fade 組件包裹它。
export default class App extends Component {
state = {
show: true
}
render () {
const circle = {
margin: 2,
width: 100,
height: 100,
position: 'absolute',
display: 'inline-block',
left: 100,
boxShadow: '0px 1px 2px #999',
textShadow: '0px 1px 2px #999',
lineHeight: '100px',
textAlign: 'center',
color: 'white',
fontSize: 10,
}
return (
<Fade inProp={this.state.show}>
<div style={circle} onClick={()=>this.setState(state=>({show: !state.show}))}>
Show
</div>
</Fade>
)
}
}
效果圖:
Props
我們來看看 Trasition 組件的其它常用屬性。
children
可以使用一個函數來代替 React 元素,通過調用這個函數與當前過渡狀態(‘enter’、‘enter’、‘exit’、‘exited’、‘unmount’),可用於將特定於上下文的props應用於組件。
type: Function | element
required
in
用於顯示組件;觸發進入或退出狀態
type: boolean
default: false
mountOnEnter
默認情況下,子組件與父轉換組件一起立即掛載。如果你想“延遲掛載”第一個in={true}上的組件,你可以設置mountOnEnter。在第一次進入轉換之後,組件將保持掛載狀態,即使在“退出”狀態下也是如此,除非你還指定unmountOnExit。
type: boolean
default: false
unmountOnExit
默認情況下,子組件在達到“退出”狀態後仍然掛載。如果你希望在組件退出後卸載組件,請設置unmountOnExit。
type: boolean
default: false
appear
通常,如果組件掛載時顯示組件,則該組件不進行轉換。如果您希望在第一個掛載集上進行轉換,則顯示爲true,並且組件將在< transition >掛載後立即進行轉換。
注意:沒有特定的“顯示”狀態。appear只添加一個額外的enter轉換。
type: boolean
default: false
enter
啓用或禁用enter轉換。
type: boolean
default: true
exit
啓用或禁用exit轉換。
type: boolean
default: true
timeout
轉換的持續時間,單位爲毫秒。
timeout={{
enter: 300,
exit: 500,
}}
type: number | { enter?: number, exit?: number }
addEndListener
添加自定義轉換結束觸發器。使用正在轉換的DOM節點和done回調調用。允許更細粒度的轉換結束邏輯。注意:如果提供超時,仍將其用作回退。
addEndListener={(node, done) => {
// use the css transitionend event to mark the finish of a transition
node.addEventListener('transitionend', done, false);
}}
type: Function
onEnter
在應用“輸入”狀態之前觸發的回調。提供了一個額外的參數isAppearing,以指示是否在初始掛載上出現了enter階段。
type: Function(node: HtmlElement, isAppearing: bool) -> void
default: function noop() {}
onEntering
在應用“輸入”狀態之前觸發的回調。提供了一個額外的參數isAppearing,以指示是否在初始掛載上出現了entering階段。
type: Function(node: HtmlElement, isAppearing: bool) -> void
default: function noop() {}
onEntered
在應用“輸入”狀態之前觸發的回調。提供了一個額外的參數isAppearing,以指示是否在初始掛載上出現了entered階段。
type: Function(node: HtmlElement, isAppearing: bool) -> void
default: function noop() {}
onExit
在應用“退出”狀態之前觸發的回調。
type: Function(node: HtmlElement) -> void
default: function noop() {}
onExiting
在應用“退出”狀態之後觸發的回調。
type: Function(node: HtmlElement) -> void
default: function noop() {}
onExited
應用“退出”狀態後觸發的回調。
type: Function(node: HtmlElement) -> void
default: function noop() {}