首页 > 解决方案 > 如何使用 React 让我的输入在段落中呈现?

问题描述

我正在处理一个待办事项列表,并且我已经为要添加的待办事项创建了功能。呈现待办事项的列表位于我创建 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;

标签: javascriptreactjsfirebasegoogle-cloud-firestorereact-props

解决方案


据我所知,您的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} />
))}

查看列表和键


推荐阅读