通过 ToDo 的小项目实战,我们可以回顾页面布局,事件的监听,React Native 中的钩子函数使用。
整体项目框架搭建以及相关基础样式
首先我们先完成项目的整体框架搭建,把页面中相关的元素和样式类名定义好。并且表明对应单独组建的位置,具体的实例如下:
<View style={
styles.container}>
{
/* 后续补充头部组建 */}
<View style={
styles.content}>
{
/* 后续补充表单组建 */}
<View style={
styles.list}>
<FlatList
data={
todo}
renderItem={
({
item }) => <Text>{
item.title}</Text>}
/>
</View>
</View>
</View>
const styles = StyleSheet.create({
container: {
flex: 1,
},
content: {
padding: 40,
},
list: {
marginTop: 20,
},
});
编写头部组件
任务列表的头部组建只是展示标题,所以在编写代码的时候比较简单
export default function header() {
return (
<View style={
styles.header}>
<Text style={
styles.title}>我的任务列表</Text>
</View>
);
}
const styles = StyleSheet.create({
header: {
height: 50,
backgroundColor: "coral",
justifyContent: "center",
},
title: {
textAlign: "center",
color: "#FFFFFF",
fontSize: 20,
fontWeight: "bold",
},
});
编写完成头部组建后,只要我们在最核心的组件中引入就可以。
编写任务组件
在整体项目搭建的时候,我们是把任务编写在根级元素上,这样我们的代码可能在维护上会比较麻烦,所以我们需要把任务项作为一个子组件来维护。具体代码如下:
// 删除任务项
const pressHandler = (id: number) => {
setTodo((prevTodos: ToDoIem[]) => prevTodos.filter((item) => item.id !== id));
};
import {
StyleSheet, Text, TouchableOpacity, View } from "react-native";
import React from "react";
interface ToDoIem {
title: string;
id: number;
}
export default function todoItem(props: {
item: ToDoIem;
pressHandler: Function;
}) {
return (
<TouchableOpacity onPress={
() => props.pressHandler(props.item.id)}>
<Text style={
styles.item}>{
props.item.title}</Text>
</TouchableOpacity>
);
}
const styles = StyleSheet.create({
item: {
padding: 16,
marginTop: 16,
borderColor: "#bbb",
borderWidth: 1,
borderStyle: "dashed",
borderRadius: 10,
},
});
编写表单组件
最后一步就是实现任务的添加,具体的代码如下:
// 添加任务项
const submitHandler = (val: string) => {
// 判断任务标题的长度
if (val.length > 3) {
setTodo((prevTodos: ToDoIem[]) => {
return [{
title: val, id: prevTodos.length + 1 }, ...prevTodos];
});
} else {
Alert.alert("信息提示", "任务名称长度必须大于3个字符", [
{
text: "关闭", onPress: () => {
} },
]);
}
};
export default function addToDo(props: {
submitHandler: Function }) {
const [text, setText] = useState<string>("");
const changeHandler = (val: string) => {
setText(val);
};
return (
<View>
<TextInput
style={
styles.input}
value={
text}
placeholder="添加任务..."
onChangeText={
(val) => changeHandler(val)}
/>
<Button
onPress={
() => {
props.submitHandler(text);
setText("");
Keyboard.dismiss();
}}
title="添加任务"
color="coral"
/>
</View>
);
}
const styles = StyleSheet.create({
input: {
marginBottom: 10,
paddingHorizontal: 8,
paddingVertical: 6,
borderBottomWidth: 1,
borderBottomColor: "#DDDDDD",
},
});
点击任何区域后收起键盘
现在我们的软件键盘是不会自己收起的,我们可以实现用户点击任何区域,软件键盘就会自动收起的效果,具体实例代码如下:
<TouchableWithoutFeedback
onPress={
() => {
Keyboard.dismiss(); // 关闭键盘
}}
>
<View style={
styles.container}>
<Header />
<View style={
styles.content}>
<AddToDo submitHandler={
submitHandler} />
<View style={
styles.list}>
<FlatList
data={
todo}
renderItem={
({
item }) => (
<TodoItem item={
item} pressHandler={
pressHandler} />
)}
/>
</View>
</View>
</View>
</TouchableWithoutFeedback>