name: react-native-web-styling user-invocable: false description: 使用React Native Web组件时进行样式设计。提供StyleSheet API、平台特定样式、响应式设计和主题化的模式。 allowed-tools:
- Read
- Write
- Edit
- Bash
- Grep
- Glob
React Native Web - 样式设计
React Native Web 的全面样式模式,包括响应式设计、主题化和平台特定样式。
关键概念
StyleSheet API
使用 StyleSheet.create() 进行优化的样式:
import { StyleSheet } from 'react-native';
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
padding: 16,
},
text: {
fontSize: 16,
color: '#333',
lineHeight: 24,
},
});
Flexbox 布局
React Native 使用 Flexbox 进行布局(默认值不同于Web):
const styles = StyleSheet.create({
// 默认 flexDirection 是 'column'(不是像Web那样的 'row')
container: {
flex: 1,
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
},
});
平台特定样式
使用 Platform.select() 为不同平台提供不同的样式:
import { Platform, StyleSheet } from 'react-native';
const styles = StyleSheet.create({
container: {
...Platform.select({
web: {
maxWidth: 1200,
marginHorizontal: 'auto',
},
native: {
paddingHorizontal: 16,
},
}),
},
});
最佳实践
响应式设计
✅ 使用基于百分比的宽度和 flexbox:
const styles = StyleSheet.create({
container: {
width: '100%',
maxWidth: 1200,
},
column: {
flex: 1,
minWidth: 300,
},
row: {
flexDirection: 'row',
flexWrap: 'wrap',
},
});
媒体查询(Web)
✅ 使用 useWindowDimensions 进行响应式行为:
import { useWindowDimensions, StyleSheet } from 'react-native';
function ResponsiveComponent() {
const { width } = useWindowDimensions();
const isDesktop = width >= 768;
return (
<View style={[styles.container, isDesktop && styles.containerDesktop]}>
{/* 内容 */}
</View>
);
}
const styles = StyleSheet.create({
container: {
padding: 16,
},
containerDesktop: {
padding: 32,
maxWidth: 1200,
},
});
主题化
✅ 创建一个主题上下文:
import React, { createContext, useContext, ReactNode } from 'react';
interface Theme {
colors: {
primary: string;
background: string;
text: string;
border: string;
};
spacing: {
xs: number;
sm: number;
md: number;
lg: number;
xl: number;
};
}
const lightTheme: Theme = {
colors: {
primary: '#007AFF',
background: '#FFFFFF',
text: '#000000',
border: '#E5E5E5',
},
spacing: {
xs: 4,
sm: 8,
md: 16,
lg: 24,
xl: 32,
},
};
const ThemeContext = createContext<Theme>(lightTheme);
export function ThemeProvider({ children }: { children: ReactNode }) {
return (
<ThemeContext.Provider value={lightTheme}>
{children}
</ThemeContext.Provider>
);
}
export function useTheme() {
return useContext(ThemeContext);
}
示例
样式化组件
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
interface ButtonProps {
title: string;
variant?: 'primary' | 'secondary';
size?: 'small' | 'medium' | 'large';
onPress: () => void;
}
export function Button({
title,
variant = 'primary',
size = 'medium',
onPress
}: ButtonProps) {
return (
<Pressable onPress={onPress}>
<View style={[styles.button, styles[variant], styles[size]]}>
<Text style={[styles.text, styles[`${variant}Text`]]}>{title}</Text>
</View>
</Pressable>
);
}
const styles = StyleSheet.create({
button: {
borderRadius: 8,
justifyContent: 'center',
alignItems: 'center',
},
primary: {
backgroundColor: '#007AFF',
},
secondary: {
backgroundColor: 'transparent',
borderWidth: 1,
borderColor: '#007AFF',
},
small: {
paddingHorizontal: 12,
paddingVertical: 6,
},
medium: {
paddingHorizontal: 16,
paddingVertical: 10,
},
large: {
paddingHorizontal: 24,
paddingVertical: 14,
},
text: {
fontWeight: '600',
},
primaryText: {
color: '#FFFFFF',
},
secondaryText: {
color: '#007AFF',
},
});
响应式网格
import React from 'react';
import { View, StyleSheet, useWindowDimensions } from 'react-native';
interface GridProps {
children: React.ReactNode;
columns?: number;
gap?: number;
}
export function Grid({ children, columns = 3, gap = 16 }: GridProps) {
const { width } = useWindowDimensions();
// 响应式列数
const responsiveColumns = width < 640 ? 1 : width < 1024 ? 2 : columns;
return (
<View style={[styles.grid, { gap }]}>
{React.Children.map(children, (child) => (
<View style={[styles.gridItem, {
width: `${100 / responsiveColumns}%`,
padding: gap / 2,
}]}>
{child}
</View>
))}
</View>
);
}
const styles = StyleSheet.create({
grid: {
flexDirection: 'row',
flexWrap: 'wrap',
margin: -8,
},
gridItem: {
flexGrow: 0,
flexShrink: 0,
},
});
阴影和高度(Elevation)
import { StyleSheet, Platform } from 'react-native';
const styles = StyleSheet.create({
card: {
backgroundColor: '#fff',
borderRadius: 8,
padding: 16,
// iOS 阴影
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
// Android 高度
elevation: 3,
// Web box-shadow(由 React Native Web 处理)
...Platform.select({
web: {
boxShadow: '0 2px 4px rgba(0, 0, 0, 0.1)',
},
}),
},
});
常见模式
动态样式
function DynamicComponent({ isActive, size }: { isActive: boolean; size: number }) {
const dynamicStyles = StyleSheet.create({
container: {
backgroundColor: isActive ? '#007AFF' : '#E5E5E5',
width: size,
height: size,
},
});
return <View style={[styles.base, dynamicStyles.container]} />;
}
样式组合
const baseStyles = StyleSheet.create({
text: {
fontSize: 16,
fontFamily: 'System',
},
});
const componentStyles = StyleSheet.create({
heading: {
...baseStyles.text,
fontSize: 24,
fontWeight: 'bold',
},
body: {
...baseStyles.text,
lineHeight: 24,
},
});
绝对定位
const styles = StyleSheet.create({
container: {
position: 'relative',
width: '100%',
height: 200,
},
overlay: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
backgroundColor: 'rgba(0, 0, 0, 0.5)',
justifyContent: 'center',
alignItems: 'center',
},
});
反模式
❌ 不要使用 CSS 类或样式表:
// 错误
<div className="container" style={{ color: 'red' }} />
// 正确
<View style={styles.container} />
❌ 不要为字体使用像素值(使用数字):
// 错误
fontSize: '16px'
// 正确
fontSize: 16
❌ 不要内联复杂样式:
// 错误
<View style={{
padding: 16,
backgroundColor: '#fff',
borderRadius: 8,
shadowColor: '#000',
// ... 更多属性
}} />
// 正确
<View style={styles.container} />
❌ 不要使用边距(margin)在列表中设置间距(使用 gap 或 paddingVertical):
// 错误
items.map((item, i) => (
<View key={item.id} style={{ marginBottom: i === items.length - 1 ? 0 : 16 }}>
{/* 内容 */}
</View>
))
// 正确
<View style={styles.list}>
{items.map((item) => (
<View key={item.id} style={styles.listItem}>
{/* 内容 */}
</View>
))}
</View>
const styles = StyleSheet.create({
list: {
gap: 16,
},
});
相关技能
- react-native-web-core:React Native Web 核心概念
- react-native-web-performance:样式性能优化
- react-native-web-testing:样式化组件测试