javascript - 如何使用 React 在我正在渲染的 UI 中渲染从两个不同输入接收到的数据?
问题描述
我正在使用 React 和 Firebase 创建一个待办事项列表。目前,我可以添加一个待办事项,并让它在 UI 中呈现,这是一个我导入和映射的列表。问题是,当我尝试添加一个额外的输入时,我无法渲染第二个输入,只有第一个输入被渲染。考虑到这一点,我决定 console.log 这两个输入,我看到数据在控制台中可用。然后我之前在 Stackoverflow 上创建了一个问题,认为我的问题是我在子组件中期望的道具。但现在,我认为我的问题在于我的数据是如何被传递、被映射然后呈现的。例如,我的 todo 作为参数传递,但是当我映射到列表元素时,我还需要将我的标题作为参数传递。
这是父组件。添加链接.js。
import { useState, useEffect } from "react";
import classes from "./addlink.module.css";
import firebase from "firebase/app";
import initFirebase from "../../config";
import "firebase/firestore";
import Todo from "../Todo/Todo";
import { v4 as uuidv4 } from "uuid";
initFirebase();
const db = firebase.firestore();
function AddLink(props) {
const [todos, setTodos] = useState([]);
const [inputLinks, setInputLinks] = useState("");
const [inputHeaders, setInputHeaders] = useState("");
useEffect(() => {
db.collection("links")
.orderBy("timestamp", "desc")
.onSnapshot((snapshot) => {
setTodos(
snapshot.docs.map((doc) => ({
id: doc.id,
todo: doc.data().todo,
}))
);
});
}, []);
const addTodo = (event) => {
event.preventDefault();
db.collection("links").add({
id: uuidv4(),
todo: inputLinks,
title: inputHeaders,
timestamp: firebase.firestore.FieldValue.serverTimestamp(),
});
console.log(inputLinks);
console.log(inputHeaders);
setInputLinks("");
setInputHeaders("");
};
return (
<div className={classes.addlink}>
<form>
<div className={classes.adminlink}>
<input
type="text"
value={inputLinks}
onChange={(event) => setInputLinks(event.target.value)}
/>
<input
type="text"
value={inputHeaders}
onChange={(event) => setInputHeaders(event.target.value)}
/>
<button
className={classes.adminbutton}
type="submit"
onClick={addTodo}
>
Add new link
</button>
</div>
</form>
{todos.map((todo, title) => (
<Todo id={todo.id} todo={todo} title={todo.title} key={todo.id} />
))}
</div>
);
}
export default AddLink;
还有子组件 Todo.js。
import React from "react";
import { AiOutlinePicture } from "react-icons/ai";
import { AiOutlineStar } from "react-icons/ai";
import { GoGraph } from "react-icons/go";
import DeleteForeverIcon from "@material-ui/icons/DeleteForever";
import classes from "./todo.module.css";
import firebase from "firebase/app";
import initFirebase from "../../config";
import "firebase/firestore";
initFirebase();
const db = firebase.firestore();
function Todo(props) {
const deleteHandler = (event) => {
db.collection("links").doc(props.todo.id).delete();
};
return (
<li className={classes.adminsection}>
<div className={classes.linkCards}>
<h3>{props.todo.title}</h3>
<p>{props.todo.todo}</p>
<div>
<AiOutlinePicture />
<AiOutlineStar />
<GoGraph />
<DeleteForeverIcon onClick={deleteHandler} />
</div>
</div>
</li>
);
}
export default Todo;
任何帮助将不胜感激。
解决方案
我想我以前也看过该代码。您以错误的方式添加数据并以错误的方式从地图中读取数据。这是一个应该如何工作的示例:
import { useState, useEffect } from "react";
import classes from "./addlink.module.css";
import firebase from "firebase/app";
import initFirebase from "../../config";
import "firebase/firestore";
import Todo from "../Todo/Todo";
import { v4 as uuidv4 } from "uuid";
initFirebase();
const db = firebase.firestore();
function AddLink(props) {
const [todos, setTodos] = useState([]);
const [inputLinks, setInputLinks] = useState("");
const [inputHeaders, setInputHeaders] = useState("");
useEffect(() => {
db.collection("links")
.orderBy("timestamp", "desc")
.onSnapshot((snapshot) => {
setTodos(
snapshot.docs.map((doc) => ({
id: doc.id,
todo: doc.data(),
}))
);
});
}, []);
const addTodo = (event) => {
event.preventDefault();
db.collection("links").add({
id: uuidv4(),
todo: inputLinks,
title: inputHeaders,
timestamp: firebase.firestore.FieldValue.serverTimestamp(),
});
console.log(inputLinks);
console.log(inputHeaders);
setInputLinks("");
setInputHeaders("");
};
return (
<div className={classes.addlink}>
<form>
<div className={classes.adminlink}>
<input
type="text"
value={inputLinks}
onChange={(event) => setInputLinks(event.target.value)}
/>
<input
type="text"
value={inputHeaders}
onChange={(event) => setInputHeaders(event.target.value)}
/>
<button
className={classes.adminbutton}
type="submit"
onClick={addTodo}
>
Add new link
</button>
</div>
</form>
{todos.map((i) => (
<Todo id={i.id} todo={i.todo} title={i.todo.title} key={i.id} />
))}
</div>
);
}
export default AddLink;
错误:
- 这里
todo
只是获取部分数据:
snapshot.docs.map((doc) => ({
id: doc.id,
todo: doc.data().todo,
}))
- 在这里你需要考虑你保存了一个对象,你需要将它作为一个对象来阅读
{todos.map((todo, title) => (
<Todo id={todo.id} todo={todo} title={todo.title} key={todo.id} />
))}
推荐阅读
- ios - 如何使用 segue 将数据从 First ViewController 直接传递到 Third View Controller?
- excel - 将二维矩阵分解为值;标题格式
- google-cloud-platform - 如何在 Apache Beam 中展平窗口化的 pcollections?[云数据流]
- angularjs - 角度指令在jsp中不起作用
- android - 即使由唯一 ID 提供,通知也不会立即显示
- node.js - 带有 Postman 请求的 Twilio Webhook
- windows - 获取适用于 Windows 的 UnxUtils tr.exe 可以像 Unix tr 一样使用字符转义
- angular - 角度迁移(从 4 到 6)e2e --proxy-config 不起作用
- python - 如何使用python中的时间戳在数据框中进行小时计算?
- c++ - 向其他方向发送消息时“需要目标地址”