name: react-native-web-core user-invocable: false description: 当处理React Native Web项目时使用。提供使用React Native构建web应用的核心概念、组件和跨平台模式。 allowed-tools:
- 读取
- 写入
- 编辑
- Bash
- Grep
- Glob
React Native Web - 核心概念
React Native Web 使React Native组件和API能够在web上运行,为web和原生平台提供统一的代码库。
关键概念
平台抽象
React Native Web 提供跨web和原生平台的一致API:
import { View, Text, StyleSheet } from 'react-native';
export function MyComponent() {
return (
<View style={styles.container}>
<Text style={styles.text}>在web和原生平台上工作!</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
text: {
fontSize: 16,
color: '#333',
},
});
核心组件
使用React Native原语代替HTML元素:
<View>代替<div><Text>代替<span>或<p><Image>代替<img><TextInput>代替<input><ScrollView>代替可滚动的<div><Pressable>代替<button>
平台特定代码
使用 Platform 模块处理平台特定行为:
import { Platform } from 'react-native';
const styles = StyleSheet.create({
container: {
marginTop: Platform.select({
web: 20,
ios: 30,
android: 25,
default: 20,
}),
},
});
// 或使用 Platform.OS
if (Platform.OS === 'web') {
// web特定代码
}
最佳实践
组件结构
✅ 一致使用React Native原语:
import { View, Text, Pressable } from 'react-native';
function Button({ onPress, title }: { onPress: () => void; title: string }) {
return (
<Pressable onPress={onPress}>
<View style={styles.button}>
<Text style={styles.buttonText}>{title}</Text>
</View>
</Pressable>
);
}
类型安全
✅ 使用TypeScript进行属性类型定义:
import { ViewStyle, TextStyle, ImageStyle } from 'react-native';
interface Props {
title: string;
onPress: () => void;
style?: ViewStyle;
textStyle?: TextStyle;
disabled?: boolean;
}
export function CustomButton({ title, onPress, style, textStyle, disabled }: Props) {
// 实现
}
无障碍性
✅ 包含无障碍性属性:
<Pressable
accessibilityRole="button"
accessibilityLabel="提交表单"
accessibilityState={{ disabled: isDisabled }}
onPress={handleSubmit}
>
<Text>提交</Text>
</Pressable>
示例
基础组件
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
interface CardProps {
title: string;
description: string;
}
export function Card({ title, description }: CardProps) {
return (
<View style={styles.card}>
<Text style={styles.title}>{title}</Text>
<Text style={styles.description}>{description}</Text>
</View>
);
}
const styles = StyleSheet.create({
card: {
padding: 16,
backgroundColor: '#fff',
borderRadius: 8,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
},
title: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 8,
},
description: {
fontSize: 14,
color: '#666',
},
});
交互式组件与状态
import React, { useState } from 'react';
import { View, Text, Pressable, StyleSheet } from 'react-native';
export function Counter() {
const [count, setCount] = useState(0);
return (
<View style={styles.container}>
<Text style={styles.count}>{count}</Text>
<View style={styles.buttons}>
<Pressable style={styles.button} onPress={() => setCount(c => c - 1)}>
<Text style={styles.buttonText}>-</Text>
</Pressable>
<Pressable style={styles.button} onPress={() => setCount(c => c + 1)}>
<Text style={styles.buttonText}>+</Text>
</Pressable>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
alignItems: 'center',
padding: 20,
},
count: {
fontSize: 48,
fontWeight: 'bold',
marginBottom: 20,
},
buttons: {
flexDirection: 'row',
gap: 10,
},
button: {
backgroundColor: '#007AFF',
paddingHorizontal: 24,
paddingVertical: 12,
borderRadius: 8,
},
buttonText: {
color: '#fff',
fontSize: 24,
fontWeight: 'bold',
},
});
常见模式
使用Flexbox布局
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
},
header: {
height: 60,
backgroundColor: '#f8f8f8',
},
content: {
flex: 1,
padding: 16,
},
footer: {
height: 50,
backgroundColor: '#f8f8f8',
},
});
条件渲染
function UserProfile({ user }: { user?: User }) {
if (!user) {
return (
<View style={styles.center}>
<Text>请登录</Text>
</View>
);
}
return (
<View style={styles.profile}>
<Text style={styles.name}>{user.name}</Text>
<Text style={styles.email}>{user.email}</Text>
</View>
);
}
反模式
❌ 不要直接使用HTML元素:
// 错误
function Component() {
return <div><span>文本</span></div>;
}
// 正确
function Component() {
return <View><Text>文本</Text></View>;
}
❌ 不要使用CSS类:
// 错误
<div className="container">内容</div>
// 正确
<View style={styles.container}>内容</View>
❌ 不要直接访问DOM:
// 错误
document.getElementById('my-element')
// 正确 - 使用refs
const ref = useRef<View>(null);
相关技能
- react-native-web-styling:高级样式模式和响应式设计
- react-native-web-navigation:导航设置和路由
- react-native-web-performance:性能优化技术
- react-native-web-testing:React Native Web的测试策略