使用Skia时Reanimated报错:UI线程同步调用非worklet函数
React Native Skia 与 Reanimated 动画 Hooks 报错修复方案
核心问题定位
你的问题源于Skia 0.1.222与Reanimated 3.5.4的版本兼容性冲突,加上可能的配置或代码写法不规范,导致官方示例也无法正常运行。
具体修复步骤
1. 调整版本兼容性
Skia 0.1.222对Reanimated 3.5.x的支持存在兼容问题,建议:
- 降级Reanimated到3.3.0(经大量用户验证的兼容版本):
npm install react-native-reanimated@3.3.0 --save-exact
- 或升级Skia到最新稳定版(0.1.230+),操作前请备份项目代码:
npm install @shopify/react-native-skia@latest --save
2. 校验Reanimated Babel配置
确保babel.config.js中正确添加Reanimated插件,且放在所有插件的最后:
module.exports = { presets: ['module:metro-react-native-babel-preset'], plugins: [ // 其他项目插件(如React Native SVG等) 'react-native-reanimated/plugin', ], };
3. 规范代码写法
所有涉及Skia动画的逻辑必须严格遵循Reanimated的worklet规则:
- 依赖Reanimated值的计算函数必须添加
'worklet'装饰器 - 启动动画需通过
runOnUI切换到UI线程执行
示例正确代码:
import { useEffect } from 'react'; import { useSharedValue, withTiming, runOnUI } from 'react-native-reanimated'; import { Canvas, Circle } from '@shopify/react-native-skia'; export default function SkiaAnimationDemo() { const progress = useSharedValue(0); useEffect(() => { runOnUI(() => { progress.value = withTiming(1, { duration: 1000 }); })(); }, []); const circleOpacity = useDerivedValue(() => { 'worklet'; return progress.value; }); return ( <Canvas style={{ flex: 1 }}> <Circle cx={150} cy={150} r={80} color={`rgba(66, 133, 244, ${circleOpacity.value})`} /> </Canvas> ); }
4. 彻底清理缓存
- 清理Metro缓存:
npx react-native start --reset-cache
- 清除iOS Pod缓存(iOS项目):
cd ios && pod deintegrate && pod install && cd ..
- 清除Android构建缓存(Android项目):
cd android && ./gradlew clean && cd ..
- 极端情况可删除依赖文件重新安装:
rm -rf node_modules package-lock.json yarn.lock npm install
5. 验证官方示例
完成上述操作后,重新运行官方动画示例,确保所有动画逻辑都符合worklet规范,避免在Skia组件props中直接使用未标记worklet的函数。
内容的提问来源于stack exchange,提问作者amir
相关产品推荐
相关产品推荐

