React+Firebase日历应用点击按钮自动生成已填内容卡片功能咨询
问题描述
我开发了一款日历应用,页面下方设置了若干可填写的文本输入框。目前Firebase运行无异常,用户填写的所有内容都能正常存入数据库。我现在需要实现以下功能:用户填写完所有字段内容后点击提交按钮,即可自动生成卡片组件展示刚刚填写的内容。
操作页示意图如下:
点击按钮后生成的卡片预期效果如下:
当前项目相关代码如下:
import React, { useState } from "react"; import { makeStyles } from "@material-ui/core/styles"; import TextField from "@material-ui/core/TextField"; import Card from "@material-ui/core/Card"; import CardActions from "@material-ui/core/CardActions"; import CardContent from "@material-ui/core/CardContent"; import Button from "@material-ui/core/Button"; import Typography from "@material-ui/core/Typography"; import Paper from "@material-ui/core/Paper"; import { Checkbox, Container, Slide } from "@material-ui/core"; import Icon from "@material-ui/core/Icon"; import { StyleSheet } from "react-native"; import firebase from "firebase/app"; import "firebase/firestore"; import { db } from "../../firebase"; import { ScrollView } from "react-native-gesture-handler"; export default function DateAndTimePickers() { const classes = useStyles(); const [ort, setOrt] = useState(""); const [notiz, setNotiz] = useState(""); const [hinweis, setHinweis] = useState(""); const [eintragen, setEintragen] = useState([]); const [dateandtime, setDateandtime] = useState([]); function handelDateandTime(e) { setDateandtime(e.target.value); } function handelOrt(e) { setOrt(e.target.value); } function handelNotiz(e) { setNotiz(e.target.value); } function handelHinweis(e) { setHinweis(e.target.value); } function KalenderEintrag() { db.collection("Eintrag") .doc() .set({ ort, notiz, hinweis, dateandtime, }) .then(() => { //If you wish to push the written data to your local state, you can do it here setEintragen([...eintragen, { ort, notiz, hinweis, dateandtime }]); console.log("Documents saved succesfully"); }) .catch((err) => { console.log(err); }); } return ( <ScrollView style={styles.root}> <Container> <TextField id="datetime-local" label="Neues Ereigniss" type="datetime-local" defaultValue="2021-09-16T10:30" className={classes.root} InputLabelProps={{ shrink: true, }} onChange={(value) => { handelDateandTime(value); }} /> </Container> {/* ORT */} <Container className={classes.ortContainer}> <TextField id="standard-helperText" label="Ort" defaultValue="Text" onChange={(value) => { handelOrt(value); }} /> </Container> {/* Hinweis */} <Container className={classes.ortContainer}> <TextField id="standard-helperText" label="Hinweis" defaultValue="Text" onChange={(value) => { handelHinweis(value); }} /> </Container> {/* Notizen */} <Container className={classes.ortContainer}> <TextField id="standard-helperText" label="Notizen" defaultValue="Text" onChange={(value) => { handelNotiz(value); }} /> </Container> <Container> <Button onClick={() => KalenderEintrag()} className={classes.btn} variant="outlined">Absenden</Button> </Container> {/* Kalender einträge */} <Card className={classes.card}> <CardContent> <Typography className={classes.title} color="textSecondary" gutterBottom > AUSFLUG </Typography> <Typography variant="h5" component="h2"> Wilheminenberg </Typography> <Typography className={classes.pos} color="textSecondary"> Jause wird mitgegeben </Typography> <Typography variant="body2" component="p"> Am 13.9.21 von 09:00 - 13:00 <br /> {"Abholung erfolgt im KG"} </Typography> </CardContent> <CardActions> <Button size="small" variant="outlined"> Zur Kenntniss genommen </Button> </CardActions> </Card> </ScrollView> ); } //material UI style const useStyles = makeStyles({ root: { marginTop: 30, marginLeft: 16, }, card: { marginTop: 30, marginLeft: 15, marginRight: 15, }, bullet: { display: "inline-block", margin: "0 2px", transform: "scale(0.8)", }, title: { fontSize: 14, }, pos: { marginBottom: 12, }, table: { marginTop: 30, }, ortContainer: { marginTop: 30, marginLeft: 15, marginRight: 15, }, btn:{ marginTop: 20, marginLeft: 15, } }); //React native style const styles = StyleSheet.create({ root: { backgroundColor: "white", }, });
解决方案
你已经实现了提交数据同步到本地eintragen状态的逻辑,只需将写死的示例卡片替换为遍历eintragen数组渲染动态卡片即可,同时修复几个代码小问题优化使用体验:
- 修正
dateandtime初始值错误,应该是字符串类型不是数组 - 简化输入框
onChange回调,无需额外嵌套箭头函数 - 提交成功后清空输入框
- 新增时间格式化函数,将
datetime-local的原始输出转换为你需要的展示格式
修改后的完整代码如下:
import React, { useState } from "react"; import { makeStyles } from "@material-ui/core/styles"; import TextField from "@material-ui/core/TextField"; import Card from "@material-ui/core/Card"; import CardActions from "@material-ui/core/CardActions"; import CardContent from "@material-ui/core/CardContent"; import Button from "@material-ui/core/Button"; import Typography from "@material-ui/core/Typography"; import Paper from "@material-ui/core/Paper"; import { Checkbox, Container, Slide } from "@material-ui/core"; import Icon from "@material-ui/core/Icon"; import { StyleSheet } from "react-native"; import firebase from "firebase/app"; import "firebase/firestore"; import { db } from "../../firebase"; import { ScrollView } from "react-native-gesture-handler"; export default function DateAndTimePickers() { const classes = useStyles(); const [ort, setOrt] = useState(""); const [notiz, setNotiz] = useState(""); const [hinweis, setHinweis] = useState(""); const [eintragen, setEintragen] = useState([]); // 修正初始值为字符串 const [dateandtime, setDateandtime] = useState(""); function handelDateandTime(e) { setDateandtime(e.target.value); } function handelOrt(e) { setOrt(e.target.value); } function handelNotiz(e) { setNotiz(e.target.value); } function handelHinweis(e) { setHinweis(e.target.value); } function KalenderEintrag() { db.collection("Eintrag") .doc() .set({ ort, notiz, hinweis, dateandtime, }) .then(() => { setEintragen([...eintragen, { ort, notiz, hinweis, dateandtime }]); console.log("Documents saved succesfully"); // 提交后清空输入框 setOrt(""); setNotiz(""); setHinweis(""); setDateandtime(""); }) .catch((err) => { console.log(err); }); } // 时间格式化函数 const formatDate = (dateStr) => { const date = new Date(dateStr); const year = date.getFullYear().toString().slice(2); const month = date.getMonth() + 1; const day = date.getDate(); const hour = date.getHours().toString().padStart(2, '0'); const minute = date.getMinutes().toString().padStart(2, '0'); return `Am ${day}.${month}.${year} von ${hour}:${minute}` } return ( <ScrollView style={styles.root}> <Container> <TextField id="datetime-local" label="Neues Ereigniss" type="datetime-local" value={dateandtime} className={classes.root} InputLabelProps={{ shrink: true, }} onChange={handelDateandTime} /> </Container> {/* ORT */} <Container className={classes.ortContainer}> <TextField id="standard-helperText" label="Ort" value={ort} onChange={handelOrt} /> </Container> {/* Hinweis */} <Container className={classes.ortContainer}> <TextField id="standard-helperText" label="Hinweis" value={hinweis} onChange={handelHinweis} /> </Container> {/* Notizen */} <Container className={classes.ortContainer}> <TextField id="standard-helperText" label="Notizen" value={notiz} onChange={handelNotiz} /> </Container> <Container> <Button onClick={KalenderEintrag} className={classes.btn} variant="outlined">Absenden</Button> </Container> {/* 动态渲染所有提交的卡片 */} {eintragen.map((item, index) => ( <Card key={index} className={classes.card}> <CardContent> <Typography className={classes.title} color="textSecondary" gutterBottom > EREIGNIS </Typography> <Typography variant="h5" component="h2"> {item.ort} </Typography> <Typography className={classes.pos} color="textSecondary"> {item.hinweis} </Typography> <Typography variant="body2" component="p"> {formatDate(item.dateandtime)} <br /> {item.notiz} </Typography> </CardContent> <CardActions> <Button size="small" variant="outlined"> Zur Kenntniss genommen </Button> </CardActions> </Card> ))} </ScrollView> ); } //material UI style const useStyles = makeStyles({ root: { marginTop: 30, marginLeft: 16, }, card: { marginTop: 30, marginLeft: 15, marginRight: 15, }, bullet: { display: "inline-block", margin: "0 2px", transform: "scale(0.8)", }, title: { fontSize: 14, }, pos: { marginBottom: 12, }, table: { marginTop: 30, }, ortContainer: { marginTop: 30, marginLeft: 15, marginRight: 15, }, btn:{ marginTop: 20, marginLeft: 15, } }); //React native style const styles = StyleSheet.create({ root: { backgroundColor: "white", }, });
内容的提问来源于stack exchange,提问作者chin14
相关产品推荐
相关产品推荐

