REACT JS:如何在地图内向尚未启动的数组添加键?

REACT JS: How to add a Key to an array that hasn't been initiated, inside a map?

我已经尝试了几天来解决这段代码,并且已经成功地慢慢地完成了它,但我仍然很遗憾地卡在了这个问题上:

首先,我想要实现的是显示一个 X 数组,其中所有值都从 1 开始有人给了我提示,我尝试了一下,但它似乎没有用,可能是因为我我没有给它分配“钥匙”

const [cantidad, setCantidad] = useState( new Array(libros.length).fill(1) );

如果我没记错的话,这应该会创建一个所有值都从 1 开始的数组。

但这是正在打印的内容:

当我至少将 1 作为值手动分配给第一个时,它看起来像这样:

但是因为我只是手动设置 const [cantidad, setCantidad] = useState([1]); 它显然不会工作,因为它只是第一个值,这就是为什么我尝试前面的代码 const [cantidad, setCantidad] = useState( new Array(libros.length).fill(1) ); 但那没有可悲地工作(或者也许我只是缺少关键组件),因为这是它给我的错误(虽然我什至没有使用 li/list)这里是它发送给我的基本上是一个 list/key 信息但似乎 key 相当于我在开始时给出的“索引”值 Lists and Keys.

无论如何,我们的想法是增加数字的 amount/cantidad 有两个函数叫做 masmenos,如果你点击左边的按钮就很简单了它添加 + 1 如果是右边的那个它会做 -1 我认为正确覆盖:

const mas = (index) => {
        setCantidad(cantidad[index] + 1);
      };

      const menos = (index) => {
        if (cantidad[index] > 0){
            setCantidad(cantidad[index] - 1);
        }
        else {
            window.alert("Sorry, Zero limit reached");
            setCantidad(0);
        }
      };

最后这就是我打印 table

的方式
<tbody>
                {libros.map((libros, index) => (
                        <tr >
                        <td>
                            <button onClick = {() => mas(index)}/>
                            {cantidad[index]}
                            {console.log(cantidad)}
                            {console.log([index])}
                            <button onClick = {() => menos(index)}/>
                        </td>
                        <td>{libros.grado}</td>

                        <td >
                        <input onChange = {(event) => {
                            let checked = event.target.checked;
                        }} 
                        
                        type="checkbox" checked = "">
                        </input>
                        {libros.descripcion}
                        </td>

                        <td >{libros.editorial}</td>
                        <td >${parseFloat(libros.precio).toFixed(2) * cantidad[index]}</td>
                        </tr>

                     ))}
                </tbody>

这是控制台日志显示的内容:

我已阅读 array and map 我了解常规情况的基础知识 没有看到我当前情况的类似示例 任何 help/tips 非常感谢,这是我的实际代码(完整代码):

import React, { useState, useEffect } from 'react'
import { auth, db } from './firebase';
import { useHistory } from 'react-router-dom';
import { Checkbox } from '@material-ui/core';

function CrearPedidos({user}) {
    const [libros, setLibros] = useState([]);
    const [cantidad, setCantidad] = useState( new Array(libros.length).fill(1));

    const history = useHistory("");
    const [totalPrice, setTotalPrice] = useState();

    const librosRef = db.collection('libros');
    const queryRef = librosRef.where('grado', '==', '4° Grado');

   console.log(cantidad)

    useEffect(() => {
        queryRef.orderBy("precio")
        .get()
        .then((snapshot) => {
              const tempData = [];
            snapshot.forEach((doc) => {

              const data = doc.data();
              tempData.push(data);
            });
            setLibros(tempData);
          });
      }, []);

      const mas = (index) => {
        setCantidad(cantidad[index] + 1);
      };

      const menos = (index) => {
        if (cantidad[index] > 0){
            setCantidad(cantidad[index] - 1);
        }
        else {
            window.alert("Sorry, Zero limit reached");
            setCantidad(0);
        }
      };

    return (
        <div className="listado_Pedidos"> 
        <div className="estudiantes_container">
            <h1 className = "estudiantes_container_h1">Estudiante: {user.displayName}</h1>
            <h1 className = "estudiantes_container_h1">Libros Nuevos</h1>
            <div className ="tableContainer">
            <table>
                <thead>
                    <tr className="Lista">
                        <th>Cantidad</th>
                        <th>Grado</th>
                        <th>Descripcion</th>
                        <th>Editorial</th>
                        <th>Precio</th>
                    </tr>
                </thead>
                <tbody>
                {libros.map((libros, index) => (
                        <tr >
                        <td>
                            <button onClick = {() => mas(index)}/>
                            {cantidad[index]}
                            {console.log(cantidad)}
                            {console.log([index])}
                            <button onClick = {() => menos(index)}/>
                        </td>
                        <td>{libros.grado}</td>

                        <td >
                        <input onChange = {(event) => {
                            let checked = event.target.checked;
                        }} 
                        
                        type="checkbox" checked = "">
                        </input>
                        {libros.descripcion}
                        </td>

                        <td >{libros.editorial}</td>
                        <td >${parseFloat(libros.precio).toFixed(2) * cantidad[index]}</td>
                        </tr>

                     ))}
                </tbody>
            </table>
            </div>

            <div className="space" />
            <button onClick="{realizarPedidos}" className = "crear_estudiante_boton">Realizar Pedidos</button>
            <div className="space" />
      </div>

      </div>
    )
}

export default CrearPedidos

我知道我最近做了很多问题,但我想尽我所能地学习和练习,哦,我也在为我的数据库使用 Firebase,唯一不来自数据库的值是 cantidad/amount all其他 grado/course descripcion/description 等来自数据库,这就是为什么我没有遇到这些问题的原因。

你的问题有点不清楚,但我在你的代码中发现了以下问题。

您正在使用另一个状态 libros 将默认值设置为 cantidad 状态,但它只会在您的组件首次呈现时设置一次。 因此,只要 libros 发生变化,您就应该在此处使用 useEffect 挂钩来更新 cantidad

useEffect(()=>{
  setCantidad(new Array(libros.length).fill(1))
}, [libros])

在遍历某些数组和渲染组件列表时始终使用键。

{libros.map((libros, index) => (
    <tr key={libros.id || index}>
      ...
    </tr>
)}