react-native-web-core
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseReact Native Web - Core Concepts
React Native Web - 核心概念
React Native Web enables React Native components and APIs to run on the web, providing a unified codebase for web and native platforms.
React Native Web 支持React Native组件和API在Web端运行,为Web和原生平台提供统一的代码库。
Key Concepts
核心概念
Platform Abstraction
平台抽象
React Native Web provides a consistent API across web and native platforms:
typescript
import { View, Text, StyleSheet } from 'react-native';
export function MyComponent() {
return (
<View style={styles.container}>
<Text style={styles.text}>Works on web and native!</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
text: {
fontSize: 16,
color: '#333',
},
});React Native Web 为Web和原生平台提供一致的API:
typescript
import { View, Text, StyleSheet } from 'react-native';
export function MyComponent() {
return (
<View style={styles.container}>
<Text style={styles.text}>Works on web and native!</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
text: {
fontSize: 16,
color: '#333',
},
});Core Components
核心组件
Use React Native primitives instead of HTML elements:
- instead of
<View><div> - instead of
<Text>or<span><p> - instead of
<Image><img> - instead of
<TextInput><input> - instead of scrollable
<ScrollView><div> - instead of
<Pressable><button>
使用React Native原生组件替代HTML元素:
- 替代
<View><div> - 替代
<Text>或<span><p> - 替代
<Image><img> - 替代
<TextInput><input> - 替代可滚动的
<ScrollView><div> - 替代
<Pressable><button>
Platform-Specific Code
平台特定代码
Use module for platform-specific behavior:
Platformtypescript
import { Platform } from 'react-native';
const styles = StyleSheet.create({
container: {
marginTop: Platform.select({
web: 20,
ios: 30,
android: 25,
default: 20,
}),
},
});
// Or use Platform.OS
if (Platform.OS === 'web') {
// Web-specific code
}使用模块实现平台特定行为:
Platformtypescript
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端特定代码
}Best Practices
最佳实践
Component Structure
组件结构
✅ Use React Native primitives consistently:
typescript
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>
);
}✅ 始终使用React Native原生组件:
typescript
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>
);
}Type Safety
类型安全
✅ Use TypeScript for prop types:
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) {
// Implementation
}✅ 使用TypeScript定义属性类型:
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) {
// 实现代码
}Accessibility
无障碍访问
✅ Include accessibility props:
typescript
<Pressable
accessibilityRole="button"
accessibilityLabel="Submit form"
accessibilityState={{ disabled: isDisabled }}
onPress={handleSubmit}
>
<Text>Submit</Text>
</Pressable>✅ 包含无障碍属性:
typescript
<Pressable
accessibilityRole="button"
accessibilityLabel="Submit form"
accessibilityState={{ disabled: isDisabled }}
onPress={handleSubmit}
>
<Text>Submit</Text>
</Pressable>Examples
示例
Basic Component
基础组件
typescript
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',
},
});typescript
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',
},
});Interactive Component with State
带状态的交互组件
typescript
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',
},
});typescript
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',
},
});Common Patterns
常见模式
Layout with Flexbox
Flexbox布局
typescript
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
},
header: {
height: 60,
backgroundColor: '#f8f8f8',
},
content: {
flex: 1,
padding: 16,
},
footer: {
height: 50,
backgroundColor: '#f8f8f8',
},
});typescript
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
},
header: {
height: 60,
backgroundColor: '#f8f8f8',
},
content: {
flex: 1,
padding: 16,
},
footer: {
height: 50,
backgroundColor: '#f8f8f8',
},
});Conditional Rendering
条件渲染
typescript
function UserProfile({ user }: { user?: User }) {
if (!user) {
return (
<View style={styles.center}>
<Text>Please log in</Text>
</View>
);
}
return (
<View style={styles.profile}>
<Text style={styles.name}>{user.name}</Text>
<Text style={styles.email}>{user.email}</Text>
</View>
);
}typescript
function UserProfile({ user }: { user?: User }) {
if (!user) {
return (
<View style={styles.center}>
<Text>Please log in</Text>
</View>
);
}
return (
<View style={styles.profile}>
<Text style={styles.name}>{user.name}</Text>
<Text style={styles.email}>{user.email}</Text>
</View>
);
}Anti-Patterns
反模式
❌ Don't use HTML elements directly:
typescript
// Bad
function Component() {
return <div><span>Text</span></div>;
}
// Good
function Component() {
return <View><Text>Text</Text></View>;
}❌ Don't use CSS classes:
typescript
// Bad
<div className="container">Content</div>
// Good
<View style={styles.container}>Content</View>❌ Don't access DOM directly:
typescript
// Bad
document.getElementById('my-element')
// Good - use refs
const ref = useRef<View>(null);❌ 不要直接使用HTML元素:
typescript
// 错误写法
function Component() {
return <div><span>Text</span></div>;
}
// 正确写法
function Component() {
return <View><Text>Text</Text></View>;
}❌ 不要使用CSS类:
typescript
// 错误写法
<div className="container">Content</div>
// 正确写法
<View style={styles.container}>Content</View>;❌ 不要直接操作DOM:
typescript
// 错误写法
document.getElementById('my-element')
// 正确写法 - 使用refs
const ref = useRef<View>(null);Related Skills
相关技能
- react-native-web-styling: Advanced styling patterns and responsive design
- react-native-web-navigation: Navigation setup and routing
- react-native-web-performance: Performance optimization techniques
- react-native-web-testing: Testing strategies for React Native Web
- react-native-web-styling: 高级样式模式与响应式设计
- react-native-web-navigation: 导航配置与路由
- react-native-web-performance: 性能优化技巧
- react-native-web-testing: React Native Web测试策略