簡體   English   中英

如何在反應中在映射數組中的單個元素上添加單擊事件

[英]How can I add a click event on an individual Element in a mapped array in react

當單擊與項目相對應的插入符號按鈕時,我一直在嘗試增加列表中項目的數量。 但是作為一個反應新手,我經歷了很多我學到的方法,比如使用鈎子、數組方法,但仍然沒有返回我想要的 output。

注意:我想要的 output 是為了讓用戶能夠單擊插入符號(向上或向下),這將分別觸發項目數量的增加或減少。

在這場斗爭中,我得到了一個提示,想在這里尋求幫助(所以這是我的第一次)。 我希望得到我的答案...謝謝。

import React, {useState} from 'react';
import { category } from '../categories.json';
import {
    Card,
    CardBody,
    CardTitle
  } from 'reactstrap';
  import { faCaretDown, faCaretUp } from '@fortawesome/free-solid-svg-icons'
  import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'

const Sides = () => {

    let [count, setCount] = useState(1)

    function Increment(event) {
        console.log(event.target);
        
        let sides = category[0].sides.forEach(item => {
            let targetId = event.target.dataset.id;
            item.find((item)=> item.id !== targetId)
        })
        console.log(sides.id);

        if(sides) {
            setCount(count + 1);
        }
        
    }

    const Decrement = () => {
        console.log('Decreasing');
        
    }

    function renderNames() {
        return(
            <div>
                <table>
                    <thead>
                    <tr>
                        <th>items</th>
                        <th>qty</th>
                        <th>price</th>
                        <th>check</th>
                    </tr>
                    </thead>

                    <tbody>
                {category[0].sides.map(item => (
                    <tr key={item.id}>
                        <td>{item.name}</td>
                <td style={{display: 'flex', alignItems: 'center'}}>
                <div style={{display: 'grid'}}>
                    <div onClick={Increment}  >
                        <FontAwesomeIcon icon={faCaretUp} data-id={item.id}/>
                    </div>
                    <div>
                        <FontAwesomeIcon icon={faCaretDown}/>
                    </div>
                </div>
                    {count}
                </td>
                <td>{item.price}</td>
                        <td>
                            <input type="checkbox" name="" id=""/>
                        </td>
                    </tr>
                ))}
                </tbody>
                </table>
            </div>
        );
    }

    return (
        <>
        <Card>
            <CardTitle>
            <h2>Sides list</h2>
            </CardTitle>

            <CardBody>
            <div style={{display: 'flex', padding: '5px'}}>
            {renderNames()}
            </div>
            </CardBody>
        </Card>
        </>
    )
}

export default Sides;

首先你需要開始思考 React 的方式,所以不需要data-x屬性,為了達到同樣的效果,你可以通過點擊事件傳遞項目 ID,比如

<div onClick={() => Increment(item.id)}>

但是讓我們以React的方式做更多的事情,打破你的組件讓它變得更好

首先創建一個Item組件

export const Item = ({ item }) => {
    const [count, setCount] = React.useState(0);
    const { id, name, price } = item;

    const Increment = () => {
        setCount(count + 1);
    };

    return (
        <tr>
            <td>{name}</td>
            <td style={{ display: 'flex', alignItems: 'center' }}>
                <div style={{ display: 'grid' }}>
                    <div onClick={Increment}>
                        <FontAwesomeIcon icon={faCaretUp} />
                    </div>
                    <div>
                        <FontAwesomeIcon icon={faCaretDown} />
                    </div>
                </div>
                {count}
            </td>
            <td>{price}</td>
            <td>
                <input type="checkbox" name="" id="" />
            </td>
        </tr>
    );
};

然后 map 通過 items 渲染Item組件

const Sides = () => {
    function renderNames() {
        return (
            <div>
                <table>
                    <thead>
                        <tr>
                            <th>items</th>
                            <th>qty</th>
                            <th>price</th>
                            <th>check</th>
                        </tr>
                    </thead>
                    <tbody>
                        {category[0].sides.map(item => (
                            <Item key={item.id} item={item} />
                        ))}
                    </tbody>
                </table>
            </div>
        );
    }

    return (
        <Card>
            <CardTitle>
                <h2>Sides list</h2>
            </CardTitle>

            <CardBody>
                <div style={{ display: 'flex', padding: '5px' }}>
                    {renderNames()}
                </div>
            </CardBody>
        </Card>
    );
};

您面臨的問題是您還使用一個state來更新項目計數,這將無法按預期工作,這種破壞方式,每個項目都有自己的 state 並且更新時將僅反映該項目

您的問題是您使用的是單個count ,您可以使用counts數組和 map 它與sides數組按index

sides[0]counts[0]sides[1]counts[1] ...

嘗試這個:

import React, {useState} from 'react';
import { category } from '../categories.json';
import {
    Card,
    CardBody,
    CardTitle
  } from 'reactstrap';
  import { faCaretDown, faCaretUp } from '@fortawesome/free-solid-svg-icons'
  import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'

const Sides = () => {

    let [counts, setCounts] = useState([])

    const Increment = (index) => {
      let newCounts = [...counts]
      newCounts[index] += 1
      setCounts(newCounts);        
    }

    const Decrement = (index) => {
      if (counts[index] > 0) {
        let newCounts = [...counts]
        newCounts[index] -= 1
        setCounts(newCounts);
      }
    }

    function renderNames() {
        return(
            <div>
                <table>
                    <thead>
                    <tr>
                        <th>items</th>
                        <th>qty</th>
                        <th>price</th>
                        <th>check</th>
                    </tr>
                    </thead>

                    <tbody>
                {category[0].sides.map((item, index) => (
                    <tr key={item.id}>
                        <td>{item.name}</td>
                <td style={{display: 'flex', alignItems: 'center'}}>
                <div style={{display: 'grid'}}>
                    <div onClick={() => Increment(index)}  >
                        <FontAwesomeIcon icon={faCaretUp} data-id={item.id}/>
                    </div>
                    <div  onClick={() => Decrement(index)}>
                        <FontAwesomeIcon icon={faCaretDown}/>
                    </div>
                </div>
                    {counts[index]}
                </td>
                <td>{item.price}</td>
                        <td>
                            <input type="checkbox" name="" id=""/>
                        </td>
                    </tr>
                ))}
                </tbody>
                </table>
            </div>
        );
    }

    return (
        <>
        <Card>
            <CardTitle>
            <h2>Sides list</h2>
            </CardTitle>

            <CardBody>
            <div style={{display: 'flex', padding: '5px'}}>
            {renderNames()}
            </div>
            </CardBody>
        </Card>
        </>
    )
}

export default Sides;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM