Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
120 views
in Technique[技术] by (71.8m points)

reactjs - How to fill an array with the same values X times and how to send the data correctly to a function?

I made a similar question related with arrays and maps but only half got answered which is why I'm making this one apart.

I have this code (Only relevant info):

const [libros, setLibros] = useState([]);
const [cantidad, setCantidad] = useState([1]);

//This is not finished because I'm still stuck
const mas = (index, value) => {
        setCantidad(cantidad[index] + 1);
      };

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


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

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

//I know this check is not working properly I'm strill trying to figure out this one 

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

   ))}
</tbody>

I know that in javascript you can do the following:

Array(5).fill(2)
//=> [2, 2, 2, 2, 2]

Is there a way to do something similar in React? because what I want to achieve is the following: "cantidad" will always start as 1 and then grant the ability to the user to change that amount +1 or -1 depending on how many of an item he/she wants but I do not know how to set up all the values to 1, with that being said, someone already guide me before telling me that by adding the index value on the map I can control them individually I fail to understand how to apply that on my code because I would like to send the current index and the current value of that index to the

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

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

functions that I have made, this is how is printing atm, I kind of understand it how to do it if you already set up an X amount of values in the array but not when the amount of values are based on the amount of times the map repeats I try using map.lenght but didn't work any advice/tips are welcome

enter image description here

This is the whole code

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(queryRef)

    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((l, index) => (
                        
                        <tr >
                        
                        <td>
                            <button onClick = {() => mas(index)}/>
                            {cantidad[index]}
                            <button onClick = {() => menos(index)}/>
                        </td>
                        <td>{l.grado}</td>

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

                        <td >{l.editorial}</td>
                        <td >${parseFloat(l.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

This is how it looks like and what does cantidad is showing on the logs

enter image description here

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Your setCantidad method usage needs to set a new array that includes the incremented value, not the incremented value of one of its items.

You are initializing useState with an array but later changing it from an array to just the value of one of those items in the array.

To be specific, you are initializing cantidad to be [1] which is the same as new Array(1).fill(1). However, you later set cantidad to be cantidad[index] + 1 which (assuming index is 0) would mean you are changing cantidad from [1] to 2. It went from an array with a number to just a number.

In order to maintain cantidad as an array, you should be setting it with a new array when it changes. setCantidad is simply there to update your state with a new value; it does not know or care what it was initialized with or previously set as.

So, you could update it many ways. Here's one suggestion:

const mas = (index) => {
  cantidad[index] = cantidad[index]++
  // Note how we're setting it with a new array, not the original. 
  // It is important to know how JS references objects (such as arrays) vs other types 
  // by using its pointer as the source of truth vs its pure bytes, respectively
  setCantidad([...cantidad]);
};

const menos = (index, value) => {
  if (cantidad[index] > 0){
    cantidad[index] = cantidad[index]--
    setCantidad([...cantidad]);
  } else {
    window.alert("Sorry, Zero limit reached");
    // no need to do any setting here as the indexed value should already be zero based on the condition above
  }
};

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...