關(guān)于
官方文檔
github
Reanimated是一個(gè)React Native庫,允許創(chuàng)建運(yùn)行在UI線程上的流暢動(dòng)畫和交互。
動(dòng)機(jī)
在React Native中,默認(rèn)情況下所有的更新都會(huì)延遲至少一幀,因?yàn)閁I和JS線程之間的通信是異步的。Reanimated的目標(biāo)是提供將動(dòng)畫和事件處理邏輯從JS線程轉(zhuǎn)移到UI線程的方法。通過定義Reanimated worklets來實(shí)現(xiàn)。worklets是可以被移動(dòng)到一個(gè)單獨(dú)的JavaScript虛擬機(jī)并在UI線程上同步執(zhí)行的一小段JavaScript代碼。這使得它能夠立即響應(yīng)觸摸事件,并在事件發(fā)生時(shí)同一幀內(nèi)更新UI。
版本差異
- 交互和動(dòng)畫不再使用非直觀的聲明式API編寫,可以用純JS編寫,以所謂的“worklets”的形式。
- Shared Values不僅可以攜帶基本數(shù)據(jù)類型,還可以攜帶數(shù)組、對(duì)象和函數(shù)。
- Shared Values不再直接關(guān)聯(lián)到視圖props,而是暴露一個(gè)useAnimatedStyle鉤子,它返回一個(gè)可以作為視圖樣式參數(shù)來傳遞的樣式對(duì)象。useAnimatedStyle鉤子接受一個(gè)worklet,當(dāng)它執(zhí)行時(shí),應(yīng)該返回將被應(yīng)用到關(guān)聯(lián)視圖的樣式。樣式worklet將在該worklet所使用的Shared Values發(fā)生變化時(shí)更新(庫會(huì)自動(dòng)檢測對(duì)Shared Values的依賴)。
- 動(dòng)畫可以通過兩種方式啟動(dòng),在Shared Values發(fā)生變化時(shí)觸發(fā)動(dòng)畫,或者從useAnimatedStyle鉤子返回動(dòng)畫值。
- 事件worklet最常見的情況是修改一些Shared Values。因此,對(duì)這些值所做的修改將反映在被觸發(fā)的動(dòng)畫樣式worklet中,這反過來又會(huì)導(dǎo)致一些視圖屬性被更新。為了方便,Reanimated提供了一個(gè)事件鉤子,專門與手勢處理程序庫一起工作,并允許你定義一個(gè)單獨(dú)的worklet來處理不同的事件狀態(tài)(例如,onStart,onActive等)。
問題和限制
- Android端,目前只支持Hermes JS VM
- 不支持遠(yuǎn)程調(diào)試,因?yàn)樵搸焓褂肑SI來同步本地方法訪問??梢允褂肍lipper來調(diào)試JS代碼,然而目前不支持將調(diào)試器連接到運(yùn)行在UI線程上的JS上下文。
- 從React Native傳遞給worklets的對(duì)象在JavaScript中沒有正確的prototype。因此這樣的對(duì)象不可枚舉,也就是說,你不能使用for in遍歷,擴(kuò)展操作符(...)或像Object.assign這樣的函數(shù)來處理對(duì)象。
- 使用Reanimated,你不能動(dòng)畫繪制布局的虛擬組件。例如,你不能動(dòng)畫繪制嵌套組件,因?yàn)镽eact Native把
<Text>
string1
<Text>string2</Text>
</Text>
改為
<RCTTextView>
string1
<RCTVirtualText>string2</RCTVirtualText>
</RCTTextView>
RCTVirtualText是一個(gè)虛擬組件。
安裝
React Native版本要求0.62及以上。
- 安裝依賴
yarn add react-native-reanimated
- 在babel.config.js文件中添加Reanimated的babel插件
module.exports = {
...
plugins: [
...
'react-native-reanimated/plugin',
],
};
注:Reanimated插件必須列在最后。
- 原生配置
Android端
- android/app/build.gradle
project.ext.react = [
enableHermes: true // <- here | clean and rebuild if changing
]
- MainApplication.java
import com.facebook.react.bridge.JSIModulePackage; // <- add
import com.swmansion.reanimated.ReanimatedJSIModulePackage; // <- add
...
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
...
@Override
protected String getJSMainModuleName() {
return "index";
}
@Override
protected JSIModulePackage getJSIModulePackage() {
return new ReanimatedJSIModulePackage(); // <- add
}
};
...
- proguard-rules.pro
-keep class com.facebook.react.turbomodule.** { *; }
iOS端
- 自動(dòng)安裝