首页 > 解决方案 > 如何使用 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;

任何帮助将不胜感激。

标签: javascriptreactjsfirebasereact-propsarray.prototype.map

解决方案


我想我以前也看过该代码。您以错误的方式添加数据并以错误的方式从地图中读取数据。这是一个应该如何工作的示例:

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} />
      ))}

推荐阅读