简体   繁体   中英

how to get values of state of that component that is inside map function react?

This is cart page of a ecommerce site. Here I want to get the value of each indivisual counter value and multiply that with their respective price and show it into final checkout value. Here, i had hardcoded $160 but I want to make that dynamic. How can I do that or what would be best approach to achieve that.

My cart page

import React, { useState } from 'react'
import { RiDeleteBin6Line } from "react-icons/ri"
import Counter from '../../Components/Counter/Counter'

const Products = ({ cartdetails }) => {
    const [value, setValue] = useState()
    return (
        <div className=' grid grid-cols-12 gap-4'>
            {cartdetails.length === 0 ?
                <div>No items in cart</div>
                :
                <div className=' col-span-8'>
                    {
                        cartdetails.map((data, index) => {
                            return (
                                <div className=' bg-gray-100 px-4 my-4 py-4'>
                                    <div className=' flex justify-between'>
                                        <img className=' w-24 h-24' src={data.productdetails.image} alt="" />
                                        <div className=''>
                                            <div className=' font-semibold text-lg'>
                                                {data.productdetails.name}
                                            </div>
                                            <div className=' text-gray-400 text-sm'>
                                                Color : {data.cartItems.color}
                                            </div>
                                        </div>
                                        <div>
                                            <div className='font-semibold text-lg'>${data.productdetails.price} USD</div>
                                            <div className='text-gray-400 text-sm'>Price</div>
                                        </div>

                                        <div>
                                            <div className=' font-semibold text-lg'>{data.productdetails.stock}</div>
                                            <div className='text-gray-400 text-sm'>In Stock</div>

                                        </div>
                                        <button className=' h-fit text-gray-400'>
                                            <RiDeleteBin6Line />
                                        </button>
                                    </div>

                                    <Counter count={data.cartItems.quantity} {...data.productdetails} />
                                
                                </div>
                            )
                        })
                    }
                </div>
            }

            <div className=' col-span-4  my-4  '>
                <div className=' px-4 py-8 flex flex-col gap-8 bg-gray-100'>
                    <div className=' flex  justify-between'>
                        <div className=' font-bold'>Total</div>
                        <div className=' font-semibold'>$160USD</div>
                    </div>
                    <div className=' flex justify-end '>
                        <button className=' btn w-36 font-bold'>Checkout</button>
                    </div>
                </div>
            </div>
        </div>
    )
}

export default Products

Counter Component

import React, { useState } from 'react'
import { HiOutlineMinus } from "react-icons/hi"
import { GoPlus } from "react-icons/go"
import { incrementItem, decrementItem } from '../../redux/cart/changeCartNumber'
import { useSelector, useDispatch } from 'react-redux'


const Counter = ({ count, stock, _id }) => {

    const [value, setValue] = useState(count)
    return (
        <div className='flex font-bold text-xl justify-end'>
            <div className=' flex gap-4 bg-white p-2 w-40 justify-between '>
                {/* <button className={`${state.value === 1 && "text-gray-400"}`} disabled={state.value === 1} onClick={() => dispatch(decrementItem({ _id, count }))}><HiOutlineMinus /></button> */}
                <button onClick={() => setValue(value - 1)} disabled={value === 1} className={`${value === 1 && "text-gray-400"}`} ><HiOutlineMinus /></button>
                <div>
                    {value}
                </div>
                <button onClick={() => setValue(value + 1)} disabled={value === stock} className={`${value === stock && "text-gray-400"}`}><GoPlus /></button>
            </div>
        </div>
    )
}

export default Counter

I don't know about getting the state back from a map function as it will be quite arduous for me, but why don't you try creating a totalPrice state in Products and then change the value of totalPrice by propDrilling setTotalPrice to Counter which will change its value on each and every change in their inventory (or cart).

const [totalPrice, setTotalPrice] = useState(0)

<Counter totalPrice={totalPrice} setTotalPrice={setTotalPrice} />

In counter you can

setTotalPrice(totalPrice + {whatever price it is for that specific increment/decrement}

Let me know if it works, I haven't tried it on a map function though. :)

You have to make another state in the parent component that will calculate the total on every child. your code will look like this:

 import React, { useState } from 'react' import { RiDeleteBin6Line } from "react-icons/ri" import Counter from '../../Components/Counter/Counter' const Products = ({ cartdetails }) => { const [total, setTotal] = useState() return ( <div className=' grid grid-cols-12 gap-4'> {cartdetails.length === 0? <div>No items in cart</div>: <div className=' col-span-8'> { cartdetails.map((data, index) => { return ( <div className=' bg-gray-100 px-4 my-4 py-4'> <div className=' flex justify-between'> <img className=' w-24 h-24' src={data.productdetails.image} alt="" /> <div className=''> <div className=' font-semibold text-lg'> {data.productdetails.name} </div> <div className=' text-gray-400 text-sm'> Color: {data.cartItems.color} </div> </div> <div> <div className='font-semibold text-lg'>${data.productdetails.price} USD</div> <div className='text-gray-400 text-sm'>Price</div> </div> <div> <div className=' font-semibold text-lg'>{data.productdetails.stock}</div> <div className='text-gray-400 text-sm'>In Stock</div> </div> <button className=' h-fit text-gray-400'> <RiDeleteBin6Line /> </button> </div> <Counter setTotal={setTotal} count={data.cartItems.quantity} {...data.productdetails} /> </div> ) }) } </div> } <div className=' col-span-4 my-4 '> <div className=' px-4 py-8 flex flex-col gap-8 bg-gray-100'> <div className=' flex justify-between'> <div className=' font-bold'>Total</div> <div className=' font-semibold'>{total}USD</div> </div> <div className=' flex justify-end '> <button className=' btn w-36 font-bold'>Checkout</button> </div> </div> </div> </div> ) } export default Products

And now inside the Counter component you will update that state to calculate the total.

 <button onClick={() => {setValue(value - 1); props.setTotal(prev=>prev+value-1)}} disabled={value === 1} className={`${value === 1 && "text-gray-400"}`} ><HiOutlineMinus /></button>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM