React Native核心概念 #
概述 #
React Native 基于 React,因此继承了 React 的核心概念。理解这些概念对于开发高质量的 React Native 应用至关重要。
组件 #
组件是 React Native 应用的基本构建块。每个组件描述了界面的一部分。
函数组件 #
推荐使用函数组件:
tsx
import React from 'react';
import {View, Text, StyleSheet} from 'react-native';
interface GreetingProps {
name: string;
}
const Greeting: React.FC<GreetingProps> = ({name}) => {
return (
<View style={styles.container}>
<Text style={styles.text}>Hello, {name}!</Text>
</View>
);
};
const styles = StyleSheet.create({
container: {
padding: 10,
},
text: {
fontSize: 18,
color: '#333',
},
});
export default Greeting;
类组件 #
虽然不推荐,但类组件仍然可用:
tsx
import React, {Component} from 'react';
import {View, Text} from 'react-native';
interface Props {
name: string;
}
interface State {
count: number;
}
class Counter extends Component<Props, State> {
state = {
count: 0,
};
increment = () => {
this.setState({count: this.state.count + 1});
};
render() {
return (
<View>
<Text>Hello, {this.props.name}!</Text>
<Text>Count: {this.state.count}</Text>
</View>
);
}
}
Props(属性) #
Props 是从父组件传递给子组件的数据,是只读的。
基本用法 #
tsx
interface CardProps {
title: string;
description?: string;
onPress?: () => void;
}
const Card: React.FC<CardProps> = ({title, description, onPress}) => {
return (
<TouchableOpacity onPress={onPress}>
<View style={styles.card}>
<Text style={styles.title}>{title}</Text>
{description && (
<Text style={styles.description}>{description}</Text>
)}
</View>
</TouchableOpacity>
);
};
// 使用
<Card
title="React Native"
description="跨平台移动开发框架"
onPress={() => console.log('Card pressed')}
/>
默认 Props #
tsx
interface ButtonProps {
title: string;
color?: string;
size?: 'small' | 'medium' | 'large';
}
const Button: React.FC<ButtonProps> = ({
title,
color = '#007AFF',
size = 'medium',
}) => {
const sizeStyles = {
small: {paddingVertical: 8, paddingHorizontal: 16},
medium: {paddingVertical: 12, paddingHorizontal: 24},
large: {paddingVertical: 16, paddingHorizontal: 32},
};
return (
<TouchableOpacity style={[styles.button, {backgroundColor: color}, sizeStyles[size]]}>
<Text style={styles.text}>{title}</Text>
</TouchableOpacity>
);
};
Props 传递模式 #
展开传递 #
tsx
const Parent = () => {
const config = {
title: 'My Card',
description: 'Description',
onPress: () => {},
};
return <Card {...config} />;
};
子组件传递 #
tsx
interface ContainerProps {
children: React.ReactNode;
style?: object;
}
const Container: React.FC<ContainerProps> = ({children, style}) => {
return <View style={[styles.container, style]}>{children}</View>;
};
// 使用
<Container style={{backgroundColor: '#f5f5f5'}}>
<Text>Content here</Text>
</Container>
State(状态) #
State 是组件内部管理的可变数据。当 state 改变时,组件会重新渲染。
useState Hook #
tsx
import React, {useState} from 'react';
import {View, Text, TouchableOpacity, StyleSheet} from 'react-native';
const Counter = () => {
const [count, setCount] = useState(0);
const [step, setStep] = useState(1);
const increment = () => {
setCount(count + step);
};
const decrement = () => {
setCount(count - step);
};
return (
<View style={styles.container}>
<Text style={styles.count}>{count}</Text>
<View style={styles.buttons}>
<TouchableOpacity style={styles.button} onPress={decrement}>
<Text style={styles.buttonText}>-</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.button} onPress={increment}>
<Text style={styles.buttonText}>+</Text>
</TouchableOpacity>
</View>
</View>
);
};
函数式更新 #
当新状态依赖于旧状态时,使用函数式更新:
tsx
const [count, setCount] = useState(0);
// 不推荐
setCount(count + 1);
// 推荐
setCount(prev => prev + 1);
对象状态 #
tsx
interface User {
name: string;
age: number;
email: string;
}
const [user, setUser] = useState<User>({
name: '',
age: 0,
email: '',
});
// 更新部分属性
const updateName = (name: string) => {
setUser(prev => ({...prev, name}));
};
数组状态 #
tsx
const [items, setItems] = useState<string[]>([]);
// 添加元素
const addItem = (item: string) => {
setItems(prev => [...prev, item]);
};
// 删除元素
const removeItem = (index: number) => {
setItems(prev => prev.filter((_, i) => i !== index));
};
// 更新元素
const updateItem = (index: number, newValue: string) => {
setItems(prev => prev.map((item, i) => (i === index ? newValue : item)));
};
生命周期 #
函数组件使用 Hooks 来处理生命周期相关的逻辑。
useEffect #
useEffect 用于处理副作用:
tsx
import React, {useState, useEffect} from 'react';
const UserProfile: React.FC<{userId: string}> = ({userId}) => {
const [user, setUser] = useState<User | null>(null);
const [loading, setLoading] = useState(true);
// 组件挂载时执行
useEffect(() => {
fetchUser(userId);
}, [userId]);
// 清理函数
useEffect(() => {
const subscription = subscribeToUpdates();
return () => {
subscription.unsubscribe();
};
}, []);
const fetchUser = async (id: string) => {
setLoading(true);
const data = await fetch(`/api/users/${id}`);
setUser(data);
setLoading(false);
};
if (loading) {
return <LoadingSpinner />;
}
return (
<View>
<Text>{user?.name}</Text>
</View>
);
};
useEffect 依赖数组 #
tsx
// 每次渲染后执行
useEffect(() => {
console.log('组件渲染');
});
// 仅挂载时执行
useEffect(() => {
console.log('组件挂载');
}, []);
// 依赖变化时执行
useEffect(() => {
console.log('userId 变化:', userId);
}, [userId]);
useLayoutEffect #
在 DOM 更新后同步执行,适合需要同步读取布局的场景:
tsx
import React, {useLayoutEffect, useRef} from 'react';
import {View, Text, findNodeHandle, measure} from 'react-native';
const Tooltip: React.FC = () => {
const ref = useRef<View>(null);
const [position, setPosition] = useState({x: 0, y: 0});
useLayoutEffect(() => {
if (ref.current) {
ref.current.measure((x, y, width, height, pageX, pageY) => {
setPosition({x: pageX, y: pageY});
});
}
}, []);
return <View ref={ref}>{/* ... */}</View>;
};
条件渲染 #
if 语句 #
tsx
const Greeting: React.FC<{isLoggedIn: boolean}> = ({isLoggedIn}) => {
if (isLoggedIn) {
return <Text>Welcome back!</Text>;
}
return <Text>Please log in</Text>;
};
三元运算符 #
tsx
const Status: React.FC<{isLoading: boolean}> = ({isLoading}) => {
return (
<View>
{isLoading ? <ActivityIndicator /> : <Text>Content loaded</Text>}
</View>
);
};
逻辑与运算符 #
tsx
const Notification: React.FC<{count: number}> = ({count}) => {
return (
<View>
{count > 0 && <Text>{count} unread messages</Text>}
</View>
);
};
列表渲染 #
使用 map #
tsx
const TodoList: React.FC<{items: string[]}> = ({items}) => {
return (
<View>
{items.map((item, index) => (
<Text key={index}>{item}</Text>
))}
</View>
);
};
使用 FlatList(推荐) #
tsx
import {FlatList} from 'react-native';
interface Item {
id: string;
title: string;
}
const TodoList: React.FC<{items: Item[]}> = ({items}) => {
const renderItem = ({item}: {item: Item}) => (
<View style={styles.item}>
<Text>{item.title}</Text>
</View>
);
return (
<FlatList
data={items}
renderItem={renderItem}
keyExtractor={item => item.id}
ItemSeparatorComponent={() => <View style={styles.separator} />}
ListEmptyComponent={<Text>No items</Text>}
/>
);
};
使用 SectionList #
tsx
import {SectionList} from 'react-native';
interface Section {
title: string;
data: Item[];
}
const GroupedList: React.FC<{sections: Section[]}> = ({sections}) => {
return (
<SectionList
sections={sections}
renderItem={({item}) => <Text>{item.title}</Text>}
renderSectionHeader={({section}) => (
<Text style={styles.header}>{section.title}</Text>
)}
keyExtractor={item => item.id}
/>
);
};
组件通信 #
父传子(Props) #
tsx
const Parent = () => {
const [value, setValue] = useState('');
return <Child value={value} onChange={setValue} />;
};
const Child = ({value, onChange}) => (
<TextInput value={value} onChangeText={onChange} />
);
子传父(回调函数) #
tsx
const Parent = () => {
const handleChildEvent = (data) => {
console.log('Received from child:', data);
};
return <Child onEvent={handleChildEvent} />;
};
const Child = ({onEvent}) => (
<Button onPress={() => onEvent({message: 'Hello'})} title="Send" />
);
兄弟组件通信(状态提升) #
tsx
const Parent = () => {
const [sharedValue, setSharedValue] = useState('');
return (
<View>
<SiblingA value={sharedValue} />
<SiblingB onChange={setSharedValue} />
</View>
);
};
性能优化 #
React.memo #
防止不必要的重新渲染:
tsx
const ExpensiveComponent = React.memo<Props>(({data}) => {
return <View>{/* 复杂渲染逻辑 */}</View>;
});
// 自定义比较函数
const MemoizedComponent = React.memo(
({item}) => <Item item={item} />,
(prevProps, nextProps) => prevProps.item.id === nextProps.item.id
);
useMemo #
缓存计算结果:
tsx
const ExpensiveList: React.FC<{items: Item[]}> = ({items}) => {
const sortedItems = useMemo(() => {
return items.sort((a, b) => a.name.localeCompare(b.name));
}, [items]);
return <FlatList data={sortedItems} renderItem={renderItem} />;
};
useCallback #
缓存回调函数:
tsx
const Parent = () => {
const [count, setCount] = useState(0);
const [items, setItems] = useState([]);
const handlePress = useCallback(() => {
console.log('Button pressed');
}, []);
const handleItemPress = useCallback((id: string) => {
console.log('Item pressed:', id);
}, []);
return (
<View>
<ChildButton onPress={handlePress} />
<ItemList items={items} onItemPress={handleItemPress} />
</View>
);
};
总结 #
React Native 的核心概念与 React 一致,包括:
- 组件:构建界面的基本单元
- Props:父组件传递给子组件的只读数据
- State:组件内部的可变数据
- 生命周期:组件的创建、更新和销毁过程
- Hooks:函数组件的状态管理方式
理解这些概念是开发 React Native 应用的基础。
接下来,让我们学习 React Native 的基础组件。
继续学习 基础组件,掌握 View、Text、Image 等核心组件的使用。
最后更新:2026-03-28