欢迎回到React Native学习之旅
在上一篇博客中,我们已经成功搭建了React Native开发环境并创建了第一个项目。现在,让我们深入了解React Native的核心概念,这些概念将成为你开发React Native应用的基础。
作为一名有安卓、TypeScript和Web基础的开发者,你会发现很多概念对你来说并不陌生,只是在React Native中有一些细微的差别。
一、JSX语法快速上手
什么是JSX?
JSX是JavaScript XML的缩写,是一种在JavaScript中编写HTML结构的语法扩展。它由React团队发明,现在被广泛应用于React和React Native开发中。
JSX与HTML的相似之处
如果你有Web开发经验,你会发现JSX看起来非常像HTML:
// HTML
<div>
<h1>Hello World</h1>
<p>This is a paragraph</p>
</div>
// JSX
<View>
<Text>Hello World</Text>
<Text>This is a paragraph</Text>
</View>
JSX与HTML的区别
-
标签名称:React Native使用原生组件标签,如
<View>、<Text>、<Image>等,而不是Web的<div>、<p>、<img>等 - 样式:React Native使用内联样式或StyleSheet对象,而不是CSS类
-
事件处理:React Native使用驼峰命名法的事件处理器,如
onPress而不是onclick -
属性:某些属性名称不同,如
className变为style
JSX与TypeScript的结合
作为有TypeScript基础的开发者,你可以在JSX中使用TypeScript的类型系统:
interface Props {
name: string;
age: number;
}
const UserCard: React.FC<Props> = ({ name, age }) => {
return (
<View>
<Text>Name: {name}</Text>
<Text>Age: {age}</Text>
</View>
);
};
二、组件化开发思想
什么是组件?
组件是React Native应用的基本构建块,类似于安卓中的View或Web中的DOM元素。组件可以是简单的,如一个按钮,也可以是复杂的,如整个屏幕。
组件与安卓组件的对比
| 安卓组件 | React Native组件 | 用途 |
|---|---|---|
| Activity | 屏幕组件 | 显示一个完整的屏幕 |
| Fragment | 可重用组件 | 显示屏幕的一部分 |
| View | View | 通用容器组件 |
| TextView | Text | 显示文本 |
| ImageView | Image | 显示图片 |
| Button | TouchableOpacity + Text | 响应用户点击 |
| RecyclerView | FlatList | 显示列表数据 |
函数组件与类组件
React Native中有两种主要的组件类型:
- 函数组件:使用函数定义的组件,是React Native推荐的方式
const Greeting: React.FC<{ name: string }> = ({ name }) => {
return <Text>Hello, {name}!</Text>;
};
- 类组件:使用ES6类定义的组件,在需要使用生命周期方法或本地状态时使用
class Counter extends React.Component<{}, { count: number }> {
state = { count: 0 };
increment = () => {
this.setState({ count: this.state.count + 1 });
};
render() {
return (
<View>
<Text>Count: {this.state.count}</Text>
<TouchableOpacity onPress={this.increment}>
<Text>Increment</Text>
</TouchableOpacity>
</View>
);
}
}
三、Props和State
Props(属性)
Props是组件的输入数据,类似于函数的参数或安卓中的Intent extras。Props是只读的,组件不能修改自己的props。
interface Props {
title: string;
subtitle?: string; // 可选属性
}
const Header: React.FC<Props> = ({ title, subtitle }) => {
return (
<View>
<Text>{title}</Text>
{subtitle && <Text>{subtitle}</Text>}
</View>
);
};
// 使用组件
<Header title="Welcome" subtitle="to React Native" />
State(状态)
State是组件的内部数据,用于存储可能随时间变化的值。与props不同,state是可变的。
在函数组件中,我们使用useState钩子来管理状态:
import React, { useState } from 'react';
const Counter: React.FC = () => {
const [count, setCount] = useState(0);
return (
<View>
<Text>Count: {count}</Text>
<TouchableOpacity onPress={() => setCount(count + 1)}>
<Text>Increment</Text>
</TouchableOpacity>
</View>
);
};
在类组件中,我们使用this.state和this.setState:
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
increment = () => {
this.setState({ count: this.state.count + 1 });
};
render() {
return (
<View>
<Text>Count: {this.state.count}</Text>
<TouchableOpacity onPress={this.increment}>
<Text>Increment</Text>
</TouchableOpacity>
</View>
);
}
}
Props vs State
| 特性 | Props | State |
|---|---|---|
| 来源 | 父组件传递 | 组件内部创建 |
| 可变性 | 只读 | 可变 |
| 影响 | 影响组件的渲染 | 影响组件的渲染 |
| 用途 | 传递数据和回调函数 | 存储组件内部状态 |
四、生命周期方法
什么是生命周期?
组件的生命周期是指组件从创建到销毁的整个过程,包括初始化、更新和卸载等阶段。在不同的阶段,组件会调用不同的方法,我们可以在这些方法中执行相应的操作。
类组件的生命周期方法
类组件有以下主要生命周期方法:
-
挂载阶段:
-
constructor:组件初始化 -
componentDidMount:组件挂载完成,可用于执行网络请求等操作
-
-
更新阶段:
-
componentDidUpdate:组件更新完成,可用于响应props或state的变化
-
-
卸载阶段:
-
componentWillUnmount:组件即将卸载,可用于清理资源
-
函数组件的生命周期
函数组件使用React Hooks来模拟生命周期行为:
-
挂载和更新:
-
useEffect:用于执行副作用操作,如网络请求、订阅等
-
import React, { useState, useEffect } from 'react';
const UserList: React.FC = () => {
const [users, setUsers] = useState([]);
useEffect(() => {
// 组件挂载时获取用户数据
fetchUsers();
// 组件卸载时清理
return () => {
// 清理代码,如取消订阅
};
}, []); // 空依赖数组表示只在挂载和卸载时执行
const fetchUsers = async () => {
const response = await fetch('https://api.example.com/users');
const data = await response.json();
setUsers(data);
};
return (
<View>
{users.map(user => (
<Text key={user.id}>{user.name}</Text>
))}
</View>
);
};
五、React Hooks简介
什么是Hooks?
Hooks是React 16.8引入的新特性,允许我们在函数组件中使用状态和其他React特性,而不需要编写类组件。
常用的Hooks
- useState:用于管理组件状态
- useEffect:用于处理副作用
- useContext:用于访问React Context
- useReducer:用于管理复杂状态
- useCallback:用于缓存函数
- useMemo:用于缓存计算结果
- useRef:用于引用DOM元素或保存可变值
六、实际应用示例
现在,让我们通过一个简单的示例来巩固所学的概念:
import React, { useState, useEffect } from 'react';
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
interface Props {
initialCount?: number;
title: string;
}
const CounterApp: React.FC<Props> = ({ initialCount = 0, title }) => {
const [count, setCount] = useState(initialCount);
const [isEven, setIsEven] = useState(count % 2 === 0);
useEffect(() => {
// 当count变化时更新isEven状态
setIsEven(count % 2 === 0);
}, [count]);
const increment = () => setCount(count + 1);
const decrement = () => setCount(count - 1);
const reset = () => setCount(initialCount);
return (
<View style={styles.container}>
<Text style={styles.title}>{title}</Text>
<Text style={styles.count}>{count}</Text>
<Text style={[styles.status, isEven ? styles.even : styles.odd]}>
{isEven ? 'Even' : 'Odd'}
</Text>
<View style={styles.buttons}>
<TouchableOpacity style={styles.button} onPress={increment}>
<Text style={styles.buttonText}>+</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.button} onPress={decrement}>
<Text style={styles.buttonText}>-</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.button} onPress={reset}>
<Text style={styles.buttonText}>Reset</Text>
</TouchableOpacity>
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
padding: 20,
},
title: {
fontSize: 24,
fontWeight: 'bold',
marginBottom: 20,
},
count: {
fontSize: 48,
marginBottom: 10,
},
status: {
fontSize: 20,
marginBottom: 30,
},
even: {
color: 'green',
},
odd: {
color: 'red',
},
buttons: {
flexDirection: 'row',
justifyContent: 'space-around',
width: '100%',
},
button: {
backgroundColor: '#f0f0f0',
padding: 15,
borderRadius: 5,
minWidth: 80,
alignItems: 'center',
},
buttonText: {
fontSize: 18,
fontWeight: 'bold',
},
});
export default CounterApp;
七、常见错误与注意事项
- 忘记导入组件:确保从'react-native'中导入所有需要的组件
-
使用HTML标签:记住使用React Native的组件,如
<View>而不是<div> -
直接修改state:始终使用
setState或状态更新函数来修改state -
忘记使用key:在渲染列表时,确保为每个元素提供唯一的
key属性 - 过度使用useEffect:只在必要时使用useEffect,并正确设置依赖数组
八、下一步学习计划
在掌握了这些基础概念后,我们将在后续的博客中学习:
- React Native组件系统
- 样式与布局
- 导航系统
- 数据处理
- 原生功能集成
- 性能优化
- 测试与调试
- 应用发布
总结
React Native的核心概念与你已经熟悉的安卓开发和Web开发有很多相似之处,但也有一些独特的特性。通过本文的学习,你应该已经掌握了:
- JSX语法的基本使用
- 组件化开发的思想
- Props和State的使用方法
- 组件的生命周期
- React Hooks的基本使用
这些概念将为你后续的React Native开发打下坚实的基础。在接下来的学习中,我们将通过实际示例来进一步巩固这些概念,并学习更多高级特性。
祝你学习愉快!