跳到主要内容

升级 / 迁移

破坏性变更与迁移方法。当前版本的完整 token 见设计令牌,组件 API 见组件概览


令牌迁移:旧顶层导出 → 运行期 Hook

背景

旧版 @unif/react-native-design 从顶层直接导出 colorsshadow 对象,可在模块顶层静态 import。这种写法只有单一亮色值,无法随系统亮暗切换 —— 顶层静态导出已删除:

// ❌ Incorrect:顶层 colors / shadow 导出已删除,拿不到;且只有亮色值
import { colors, shadow } from '@unif/react-native-design';

const styles = StyleSheet.create({
container: {
backgroundColor: colors.surface, // 静态,不随亮 / 暗切换
...shadow.brandLg,
},
});

迁移方式

颜色 + 阴影:改用运行期 hook。useThemedStyles(maker)maker 签名是 (c: ColorTokens, s: ShadowTokens) => StyleSheet,在组件内调用即拿到当前主题的 styles。

// ✅ Correct:运行期 hook,自动随主题切换
import { useThemedStyles } from '@unif/react-native-design';
import type { ColorTokens, ShadowTokens } from '@unif/react-native-design';
import { StyleSheet } from 'react-native';

// makeStyles 必须在模块顶层定义(不能内联进组件,否则打穿 useMemo 缓存)
const makeStyles = (c: ColorTokens, s: ShadowTokens) =>
StyleSheet.create({
container: {
backgroundColor: c.surface,
...s.brandLg, // 暗色下 shadowOpacity / elevation 自动趋零
},
});

function MyComponent() {
const styles = useThemedStyles(makeStyles);
// ...
}

只需 inline 取色时用 useColors()(返回 ColorTokens),取阴影用 useShadow()(返回 ShadowTokens)。

间距 / 圆角 / 字体 / 动效:这些是静态 token,继续直接 import:

import {
space,
radius,
type as t,
fw,
fontMono,
motion,
} from '@unif/react-native-design';

对照速查

旧写法(已删除)新写法(正确)
import { colors } from '@unif/react-native-design'const c = useColors()
import { shadow } from '@unif/react-native-design'const s = useShadow(),或 maker 第二参 (c, s) => ...
colors.primary / colors.surface / colors.foregroundc.primary / c.surface / c.foreground
shadow.brandLg...s.brandLg(spread 进 StyleSheet)
顶层 StyleSheet.create({ ... colors.x ... })useThemedStyles(maker) 运行期

旧 token 名 → 新 role 名

历史代码里若残留旧的强度档命名,grep 替换为 role 名:

colors.bgPagec.background
colors.bgCardc.surface
colors.bgInputc.surfaceContainer
colors.bgMutedc.surfaceContainerHigh
colors.bgPillc.surfaceContainerHighest
colors.fg1 / fg2 / fg3c.foreground / c.foregroundMuted / c.foregroundSubtle
colors.primary300 / 500c.primary / c.primaryPressed
colors.primary0 / 50c.primaryContainer / c.primaryContainerSubtle
colors.success300 / successBgc.success / c.successContainer
colors.error300 / error0c.error / c.errorContainer
colors.info300 / infoBgc.info / c.infoContainer
colors.border / borderSoft / borderFaintc.outline / c.outlineVariant / c.outlineFaint

brandGradient / primary100/200/400/600 等强度档已随死代码清理移除(0 消费方)。迁移对照见本页的令牌迁移表。

为什么不能继续用静态导出

ThemeProvideruseColorScheme() 动态算亮 / 暗,并以 [scheme, fontScale]useMemo 依赖,把稳定的 colors / shadow 引用和字号倍数注入 Context。useThemedStyles(maker)useMemo([colors, shadow, fontScale, maker]) 依赖这些值 —— 静态顶层导出永远只有亮色值,亮暗切换和应用级字号档位都对它无效。


版本升级注意事项

0.6.0 移除 BottomSheet;当前 Confirm 已重新提供

0.6.0 曾同时移除 BottomSheet 与旧 Confirm 实现,并去掉 @gorhom/bottom-sheet 依赖。当前版本仍不提供 BottomSheet,但已经重新公开 confirm()<ConfirmHost />ConfirmOptions;新的 Confirm 使用裸 RN Modal + 栈式 owner Store,不依赖 @gorhom

// ❌ BottomSheet 当前仍未从包根导出
import { BottomSheet } from '@unif/react-native-design';

// ✅ 当前命令式确认 API
import { ConfirmHost, confirm } from '@unif/react-native-design';

// App 根附近挂一个
function AppOverlays() {
return <ConfirmHost />;
}

async function requestDelete() {
const accepted = await confirm({
title: '确认删除?',
destructive: true,
});
// 根据 accepted 决定是否继续
}

迁移建议:

  • 底部 sheet / 弹层 → 用 React Navigation 的 presentation: 'formSheet' (原生 sheet,系统接管手势 / 动画 / 变暗),或自持 sheet 容器。
  • 命令式确认 → 使用包根导出的 confirm(),并在 SafeAreaProvider 内挂一个 <ConfirmHost />。生命周期、重入和无 Host 语义见 Confirm

同时 Toast 新增 position'top' | 'bottom' | 'center',默认 'bottom'),详见 Toast

升级 react-native-reanimated 4.x

Reanimated 4 使用新的 worklet 插件 react-native-worklets/plugin 替代旧的 react-native-reanimated/pluginbabel.config.js 里 worklets 插件必须排在 plugins 数组最后:

// babel.config.js
module.exports = {
plugins: [
// ... 其它插件
// worklets 插件必须最后
'react-native-worklets/plugin',
],
};