通过 ToDo 的小项目实战,我们可以回顾页面布局,事件的监听,React Native 中的钩子函数使用。
整体项目框架搭建以及相关基础样式
首先我们先完成项目的整体框架搭建,把页面中相关的元素和样式类名定义好。并且表明对应单独组建的位置,具体的实例如下:
<View style={styles.container}>{/* 后续补充头部组建 */}<View style={styles.content}>{/* 后续补充表单组建 */}<View style={styles.list}><FlatListdata={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><TextInputstyle={styles.input}value={text}placeholder="添加任务..."onChangeText={(val) => changeHandler(val)}/><ButtononPress={() => {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",},
});
点击任何区域后收起键盘
现在我们的软件键盘是不会自己收起的,我们可以实现用户点击任何区域,软件键盘就会自动收起的效果,具体实例代码如下:
<TouchableWithoutFeedbackonPress={() => {Keyboard.dismiss(); // 关闭键盘}}
><View style={styles.container}><Header /><View style={styles.content}><AddToDo submitHandler={submitHandler} /><View style={styles.list}><FlatListdata={todo}renderItem={({ item }) => (<TodoItem item={item} pressHandler={pressHandler} />)}/></View></View></View>
</TouchableWithoutFeedback>
完整代码
完整代码下载