如何通过单击 React 中的按钮来呈现列表?
How can I render a list by clicking a button in React?
我正在使用 React 和 Firebase 处理待办事项列表。我希望能够单击一个将添加新待办事项的按钮,但将待办事项呈现为列表项。到目前为止,我正在通过列表映射每个待办事项,但是当我添加道具时,当我将鼠标悬停在 VSC 中的错误上时,我收到错误消息 Missing "key" prop for element in iterator
。使用按钮单击呈现列表时,如何添加关键道具?如果有帮助,我将代码包含在内。
AddLink.js
import { useState, useEffect } from "react";
import classes from "./addlink.module.css";
import { AiOutlinePicture } from "react-icons/ai";
import { AiOutlineStar } from "react-icons/ai";
import { GoGraph } from "react-icons/go";
import { RiDeleteBin6Line } from "react-icons/ri";
import Modal from "../Modal/Modal";
import Backdrop from "../Backdrop/Backdrop";
import firebase from "firebase/app";
import initFirebase from "../../config";
import "firebase/firestore";
// import Links from "../Links/Links";
import Todo from "../Todo/Todo";
initFirebase();
const db = firebase.firestore();
function AddLink(props) {
const [modalIsOpen, setModalIsOpen] = useState(false);
const [todos, setTodos] = useState([]);
const [input, setInput] = 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();
console.log("clicked");
db.collection("links").add({
todo: input,
timestamp: firebase.firestore.FieldValue.serverTimestamp(),
});
// empty input after the todo is successfully stored in firebase
setInput("");
};
const deleteLink = () => {
setModalIsOpen(true);
};
const closeModalHandler = () => {
setModalIsOpen(false);
};
return (
<div className={classes.addlink}>
<form>
<div className={classes.adminlink}>
<input
type="text"
value={input}
onChange={(event) => setInput(event.target.value)}
/>
<button
className={classes.adminbutton}
type="submit"
onClick={addTodo}
>
Add new link
</button>
</div>
<div className={classes.adminsection}>
<div className="link-cards">
<h3>{props.text}</h3>
<p>This is a new link</p>
<div>
<AiOutlinePicture />
<AiOutlineStar />
<GoGraph />
<button onClick={deleteLink}>
<RiDeleteBin6Line />
</button>
</div>
</div>
</div>
{todos.map((todo) => (
<Todo todo={todo} /> //This is where I am getting the error message
))}
{modalIsOpen && (
<Modal onCancel={closeModalHandler} onConfirm={closeModalHandler} />
)}
{modalIsOpen && <Backdrop onCancel={closeModalHandler} />}
</form>
</div>
);
}
export default AddLink;
然后Todo.js
import React from "react";
function Todo(props) {
return (
<div>
<li>{props.text}</li>
</div>
);
}
export default Todo;
任何帮助将不胜感激。
有一个 index
作为 Array.map 回调函数的第二个参数
您可以将它用作渲染的关键,如果您不对列表进行任何重新排序,这是安全的。
{
todos.map((todo, index) => (
<Todo key={index} todo={todo} />
));
}
如果您想拥有列表的实际键,请尝试 uuid 库,并在添加新的待办事项时生成一个键。
像这样:
import { v4 as uuidv4 } from 'uuid';
const addTodo = event => {
event.preventDefault();
console.log("clicked");
db.collection("links").add({
id: uuidv4(), //<-- Add random unique key to your todo item
todo: input,
timestamp: firebase.firestore.FieldValue.serverTimestamp()
});
setInput("");
};
我正在使用 React 和 Firebase 处理待办事项列表。我希望能够单击一个将添加新待办事项的按钮,但将待办事项呈现为列表项。到目前为止,我正在通过列表映射每个待办事项,但是当我添加道具时,当我将鼠标悬停在 VSC 中的错误上时,我收到错误消息 Missing "key" prop for element in iterator
。使用按钮单击呈现列表时,如何添加关键道具?如果有帮助,我将代码包含在内。
AddLink.js
import { useState, useEffect } from "react";
import classes from "./addlink.module.css";
import { AiOutlinePicture } from "react-icons/ai";
import { AiOutlineStar } from "react-icons/ai";
import { GoGraph } from "react-icons/go";
import { RiDeleteBin6Line } from "react-icons/ri";
import Modal from "../Modal/Modal";
import Backdrop from "../Backdrop/Backdrop";
import firebase from "firebase/app";
import initFirebase from "../../config";
import "firebase/firestore";
// import Links from "../Links/Links";
import Todo from "../Todo/Todo";
initFirebase();
const db = firebase.firestore();
function AddLink(props) {
const [modalIsOpen, setModalIsOpen] = useState(false);
const [todos, setTodos] = useState([]);
const [input, setInput] = 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();
console.log("clicked");
db.collection("links").add({
todo: input,
timestamp: firebase.firestore.FieldValue.serverTimestamp(),
});
// empty input after the todo is successfully stored in firebase
setInput("");
};
const deleteLink = () => {
setModalIsOpen(true);
};
const closeModalHandler = () => {
setModalIsOpen(false);
};
return (
<div className={classes.addlink}>
<form>
<div className={classes.adminlink}>
<input
type="text"
value={input}
onChange={(event) => setInput(event.target.value)}
/>
<button
className={classes.adminbutton}
type="submit"
onClick={addTodo}
>
Add new link
</button>
</div>
<div className={classes.adminsection}>
<div className="link-cards">
<h3>{props.text}</h3>
<p>This is a new link</p>
<div>
<AiOutlinePicture />
<AiOutlineStar />
<GoGraph />
<button onClick={deleteLink}>
<RiDeleteBin6Line />
</button>
</div>
</div>
</div>
{todos.map((todo) => (
<Todo todo={todo} /> //This is where I am getting the error message
))}
{modalIsOpen && (
<Modal onCancel={closeModalHandler} onConfirm={closeModalHandler} />
)}
{modalIsOpen && <Backdrop onCancel={closeModalHandler} />}
</form>
</div>
);
}
export default AddLink;
然后Todo.js
import React from "react";
function Todo(props) {
return (
<div>
<li>{props.text}</li>
</div>
);
}
export default Todo;
任何帮助将不胜感激。
有一个 index
作为 Array.map 回调函数的第二个参数
您可以将它用作渲染的关键,如果您不对列表进行任何重新排序,这是安全的。
{
todos.map((todo, index) => (
<Todo key={index} todo={todo} />
));
}
如果您想拥有列表的实际键,请尝试 uuid 库,并在添加新的待办事项时生成一个键。
像这样:
import { v4 as uuidv4 } from 'uuid';
const addTodo = event => {
event.preventDefault();
console.log("clicked");
db.collection("links").add({
id: uuidv4(), //<-- Add random unique key to your todo item
todo: input,
timestamp: firebase.firestore.FieldValue.serverTimestamp()
});
setInput("");
};