Appearance
事件处理(点击、输入等)
React 基础速成
在 React 和 React Native 中,事件处理是实现用户交互的核心机制。通过事件处理,我们可以响应用户的点击、触摸、输入等操作,使应用变得更加交互性。
1. 事件处理基础
基本语法
在 React Native 中,事件处理的基本语法与 React 类似,但有一些平台特定的差异。
jsx
import { View, Text, Button } from 'react-native';
import { useState } from 'react';
export default function EventHandling() {
const [count, setCount] = useState(0);
const handlePress = () => {
setCount(count + 1);
};
return (
<View>
<Text>Count: {count}</Text>
<Button title="Increment" onPress={handlePress} />
</View>
);
}事件处理函数
事件处理函数可以是内联的箭头函数,也可以是组件中的方法:
jsx
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
import { useState } from 'react';
export default function EventHandling() {
const [count, setCount] = useState(0);
// 内联箭头函数
const handlePress = () => {
setCount(count + 1);
};
return (
<View>
<Text>Count: {count}</Text>
<TouchableOpacity
style={styles.button}
onPress={handlePress}
>
<Text style={styles.buttonText}>Increment</Text>
</TouchableOpacity>
</View>
);
}
const styles = StyleSheet.create({
button: {
backgroundColor: '#007AFF',
padding: 10,
borderRadius: 5,
marginTop: 10,
},
buttonText: {
color: 'white',
fontSize: 16,
textAlign: 'center',
},
});2. 常见事件类型
触摸事件
- onPress:点击事件
- onLongPress:长按事件
- onPressIn:按下事件
- onPressOut:松开事件
jsx
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
import { useState } from 'react';
export default function TouchEvents() {
const [message, setMessage] = useState('Tap the button');
const handlePress = () => {
setMessage('Button pressed!');
};
const handleLongPress = () => {
setMessage('Button long pressed!');
};
return (
<View>
<Text>{message}</Text>
<TouchableOpacity
style={styles.button}
onPress={handlePress}
onLongPress={handleLongPress}
>
<Text style={styles.buttonText}>Tap or Long Press</Text>
</TouchableOpacity>
</View>
);
}
const styles = StyleSheet.create({
button: {
backgroundColor: '#007AFF',
padding: 10,
borderRadius: 5,
marginTop: 10,
},
buttonText: {
color: 'white',
fontSize: 16,
textAlign: 'center',
},
});文本输入事件
- onChangeText:文本改变事件
- onSubmitEditing:提交编辑事件
- onFocus:获得焦点事件
- onBlur:失去焦点事件
jsx
import { View, Text, TextInput, StyleSheet } from 'react-native';
import { useState } from 'react';
export default function TextInputEvents() {
const [text, setText] = useState('');
const [submittedText, setSubmittedText] = useState('');
const handleChangeText = (value) => {
setText(value);
};
const handleSubmitEditing = () => {
setSubmittedText(text);
};
return (
<View>
<TextInput
style={styles.input}
placeholder="Enter text"
value={text}
onChangeText={handleChangeText}
onSubmitEditing={handleSubmitEditing}
/>
<Text>Input: {text}</Text>
<Text>Submitted: {submittedText}</Text>
</View>
);
}
const styles = StyleSheet.create({
input: {
borderWidth: 1,
borderColor: '#ccc',
padding: 10,
margin: 10,
borderRadius: 5,
},
});滚动事件
- onScroll:滚动事件
- onScrollBeginDrag:开始拖动事件
- onScrollEndDrag:结束拖动事件
jsx
import { View, Text, ScrollView, StyleSheet } from 'react-native';
import { useState } from 'react';
export default function ScrollEvents() {
const [scrollY, setScrollY] = useState(0);
const handleScroll = (event) => {
setScrollY(event.nativeEvent.contentOffset.y);
};
return (
<View>
<Text>Scroll position: {scrollY}</Text>
<ScrollView
style={styles.scrollView}
onScroll={handleScroll}
scrollEventThrottle={16} // 16ms, roughly 60fps
>
{Array.from({ length: 50 }).map((_, index) => (
<View key={index} style={styles.item}>
<Text>Item {index + 1}</Text>
</View>
))}
</ScrollView>
</View>
);
}
const styles = StyleSheet.create({
scrollView: {
flex: 1,
marginTop: 10,
},
item: {
padding: 20,
borderBottomWidth: 1,
borderBottomColor: '#ccc',
},
});3. 事件对象
当事件被触发时,React Native 会传递一个事件对象给事件处理函数,这个对象包含了事件的相关信息。
jsx
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
export default function EventObject() {
const handlePress = (event) => {
console.log('Event type:', event.type);
console.log('Timestamp:', event.nativeEvent.timestamp);
};
return (
<View>
<TouchableOpacity
style={styles.button}
onPress={handlePress}
>
<Text style={styles.buttonText}>Press me</Text>
</TouchableOpacity>
</View>
);
}
const styles = StyleSheet.create({
button: {
backgroundColor: '#007AFF',
padding: 10,
borderRadius: 5,
marginTop: 10,
},
buttonText: {
color: 'white',
fontSize: 16,
textAlign: 'center',
},
});4. 传递参数给事件处理函数
有时我们需要给事件处理函数传递额外的参数,这可以通过箭头函数来实现:
jsx
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
import { useState } from 'react';
export default function PassingParams() {
const [selectedItem, setSelectedItem] = useState('');
const handleItemPress = (itemId) => {
setSelectedItem(`Item ${itemId} selected`);
};
return (
<View>
<Text>{selectedItem}</Text>
{Array.from({ length: 5 }).map((_, index) => (
<TouchableOpacity
key={index}
style={styles.item}
onPress={() => handleItemPress(index + 1)}
>
<Text>Item {index + 1}</Text>
</TouchableOpacity>
))}
</View>
);
}
const styles = StyleSheet.create({
item: {
padding: 10,
borderBottomWidth: 1,
borderBottomColor: '#ccc',
},
});5. 事件处理的最佳实践
1. 使用箭头函数
使用箭头函数作为事件处理函数,避免 this 绑定问题:
jsx
// 推荐
const handlePress = () => {
// 处理逻辑
};
// 不推荐
function handlePress() {
// 处理逻辑
}2. 避免在渲染中创建函数
避免在渲染过程中创建新的函数,这会影响性能:
jsx
// 推荐
const handlePress = () => {
// 处理逻辑
};
return (
<TouchableOpacity onPress={handlePress}>
<Text>Press me</Text>
</TouchableOpacity>
);
// 不推荐
return (
<TouchableOpacity onPress={() => {
// 处理逻辑
}}>
<Text>Press me</Text>
</TouchableOpacity>
);3. 使用 useCallback 缓存函数
对于复杂的事件处理函数,使用 useCallback 缓存函数,避免不必要的重新渲染:
jsx
import { useCallback } from 'react';
const handlePress = useCallback(() => {
// 处理逻辑
}, []);4. 事件处理函数的命名
使用清晰、描述性的命名:
jsx
// 推荐
const handleButtonPress = () => {
// 处理逻辑
};
// 不推荐
const onPress = () => {
// 处理逻辑
};6. 常见错误与解决方案
错误 1:忘记绑定 this
错误:
jsx
import { View, Text, Button } from 'react-native';
class EventHandling extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
handlePress() {
this.setState({ count: this.state.count + 1 }); // 错误:this 未绑定
}
render() {
return (
<View>
<Text>Count: {this.state.count}</Text>
<Button title="Increment" onPress={this.handlePress} />
</View>
);
}
}
export default EventHandling;解决方案:
jsx
import { View, Text, Button } from 'react-native';
class EventHandling extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
this.handlePress = this.handlePress.bind(this); // 正确:绑定 this
}
handlePress() {
this.setState({ count: this.state.count + 1 });
}
render() {
return (
<View>
<Text>Count: {this.state.count}</Text>
<Button title="Increment" onPress={this.handlePress} />
</View>
);
}
}
export default EventHandling;错误 2:直接调用函数而不是传递函数引用
错误:
jsx
import { View, Text, Button } from 'react-native';
import { useState } from 'react';
export default function EventHandling() {
const [count, setCount] = useState(0);
const handlePress = () => {
setCount(count + 1);
};
return (
<View>
<Text>Count: {count}</Text>
<Button title="Increment" onPress={handlePress()} />
{/* 错误:直接调用了函数,而不是传递函数引用 */}
</View>
);
}解决方案:
jsx
import { View, Text, Button } from 'react-native';
import { useState } from 'react';
export default function EventHandling() {
const [count, setCount] = useState(0);
const handlePress = () => {
setCount(count + 1);
};
return (
<View>
<Text>Count: {count}</Text>
<Button title="Increment" onPress={handlePress} />
{/* 正确:传递函数引用 */}
</View>
);
}7. 总结
事件处理是 React Native 中实现用户交互的核心机制。通过事件处理,我们可以响应用户的各种操作,使应用变得更加交互性。
在 React Native 中,常见的事件包括:
- 触摸事件:onPress, onLongPress, onPressIn, onPressOut
- 文本输入事件:onChangeText, onSubmitEditing, onFocus, onBlur
- 滚动事件:onScroll, onScrollBeginDrag, onScrollEndDrag
在处理事件时,要注意:
- 使用箭头函数作为事件处理函数,避免
this绑定问题 - 避免在渲染过程中创建新的函数,影响性能
- 使用
useCallback缓存复杂的事件处理函数 - 使用清晰、描述性的命名
掌握事件处理,你可以创建出更加交互性强、用户体验更好的 React Native 应用。
下一节,我们将学习 Hooks 基础,这是 React 中管理状态和副作用的重要机制。
