【问题标题】:How can I get my input to render in a paragraph, using React?如何使用 React 让我的输入在段落中呈现?
【发布时间】:2021-09-14 04:43:18
【问题描述】:

我正在处理一个待办事项列表,并且我已经为要添加的待办事项创建了功能。呈现待办事项的列表位于我创建 addTodo 函数的单独组件中。一切似乎都很好,但是,当我单击添加 todo 时,我添加的输入不会呈现在我在 Todo 组件中创建的段落中。我还安慰了我在输入中添加的数据,它显示在控制台中。我相信我的问题在于我如何在我的 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 [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();

    db.collection("links").add({
      id: uuidv4(),
      todo: input,
      timestamp: firebase.firestore.FieldValue.serverTimestamp(),
    });
    console.log(input);
    setInput("");
  };

  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>
      </form>
      {todos.map((todo, id) => (
        <Todo todo={todo} key={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>Todo</h3>
        <p>{props.value}</p>
        <div>
          <AiOutlinePicture />
          <AiOutlineStar />
          <GoGraph />
          <DeleteForeverIcon onClick={deleteHandler} />
        </div>
      </div>
    </li>
  );
}

export default Todo;

【问题讨论】:

    标签: javascript reactjs firebase google-cloud-firestore react-props


    【解决方案1】:

    据我所知,您的todo 对象具有idtodotimestamp 属性。

    const addTodo = (event) => {
      event.preventDefault();
    
      db.collection("links").add({
        id: uuidv4(),
        todo: input,
        timestamp: firebase.firestore.FieldValue.serverTimestamp(),
      });
      setInput("");
    };
    

    links 集合更新时,您会将其全部映射到状态中的todo 属性中。

    useEffect(() => {
      db.collection("links")
        .orderBy("timestamp", "desc")
        .onSnapshot((snapshot) => {
          setTodos(
            snapshot.docs.map((doc) => ({
              id: doc.id,
              todo: doc.data().todo,
            }))
          );
        });
    }, []);
    

    您映射它并将 整个 todo 属性作为道具传递。

     {todos.map((todo, id) => (
       <Todo todo={todo} key={id} />
     ))}
    

    最后在Todo 中,您可以访问value 属性。

    <p>{props.value}</p>
    

    这不是一个定义的值。

    看来您应该访问 props.todo.todo 属性。

    <p>{props.todo.todo}</p>
    

    我可能在嵌套级别以及onSnapshot 订阅解包的内容上弄错了,所以它可能只是props.todo

    <p>{props.todo}</p>
    

    但鉴于在deleteHandler 中您似乎正确引用了props.todo.id,我确定您需要在段落中访问props.todo.todo

    注意事项

    在映射数组时,如果你正在改变数组(在中间插入、删除元素等),那么不要使用数组索引作为 React 键,因为一旦你改变了数组,键就会转移到不同的位置元素。使用doc.id,因为这将是每个元素的内在价值。

    {todos.map((todo) => (
      <Todo todo={todo} key={todo.id} />
    ))}
    

    Lists & Keys

    【讨论】:

    • 你当然是对的。感谢您提供的细分和良好的解释。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-26
    • 2021-02-26
    • 1970-01-01
    • 2020-05-21
    • 2021-11-07
    相关资源
    最近更新 更多