首页 > 解决方案 > 获取反应组件中的最新值

问题描述

所以我正在尝试使用图标创建添加到收藏夹按钮。到目前为止,如果用户单击空心图标变成全心图标并且我能​​够找到它被单击的项目,我可以制定逻辑。

到目前为止一切顺利,我的问题开始于products对象仅收到最近挑选的物品并丢失之前挑选的其他物品时。

因此,例如,如果我想单击 3 个项目以将它们添加到收藏夹中,我看到console.log(favProduct)唯一保留了我的案例编号 3 中的最新项目并丢失了编号 1 和 2。

我的问题是如何获取我点击的所有项目,而不仅仅是最近的项目。

编辑这是我从中获取产品的地方,请检查下面的代码。

import React , { useState, useEffect } from 'react'
import { Row , Col } from 'react-bootstrap'
import Product from '../components/Product'
import axios from 'axios'

const HomeScreen = () =>{
    const [products , setProducts]  = useState([])
    useEffect(()=>{
        let componentMounted = true
        const fetchProducts = async () =>{
            const {data} = await axios.get('http://172.30.246.130:5000/api/products')
            if( componentMounted){

                setProducts(data)
            }
        }
        fetchProducts()
        return () =>{
            componentMounted = false
        }
    },[])
    console.log('products' , products)
    return(
        <>
        <h2 className='my-3'>Latest Products</h2>
        <Row>
            {
                products.map((product)=>(
                    <Col key={product._id} sm={12} md={6} lg={4} xl={3}>
                    <Product product={product} rating = {product.rating} reviews={product.numReviews}/>
                    </Col>
                ))
            }
        </Row>
        </>
    )
}
export default HomeScreen

import React, { useState } from 'react'

const Fav = ({products}) => {
    let [checked , setChecked] = useState(false)
    let[favProduct ,setFavProduct] = useState([])
    const toggle = ()=>{
        (!checked) ? setChecked(true) : setChecked(false)
        setFavProduct([...favProduct,products]) // problem is here

    }
    console.log(favProduct)
    return (
        <>
        <span onClick={toggle}>
            {
                <i className={(checked) ? "fas fa-heart" : "far fa-heart"}></i>
            }
        </span>
        </>
    )
}
export default Fav

标签: javascriptreactjs

解决方案


目前,您的每个Fav组件看起来都在尝试管理所有收藏夹的状态,这不是一个好主意。

总的想法是让大多数 UI 组件尽可能地愚蠢(即,在给定它们的道具的情况下只返回最低限度)。他们可以控制自己的状态,但通常您希望父母通过提升状态来控制状态,并让他们传递一个处理程序,当他们的侦听器被触发时,哑组件可以调用该处理程序。

在这个例子中,Fav接受一个id、一个favoured和一个handleClick监听器,然后只返回一些 JSX。

父组件负责所有的状态管理。

const { useEffect, useState } = React;

// Accept some props
// Render the class based on the `favoured` prop
function Fav({ id, favoured, handleClick }) {
  return (
    <div className="icon">
      <i
        data-id={id}
        className={favoured ? 'fa-solid fa-heart' : 'fa-regular fa-heart'}
        onClick={handleClick}
      >&nbsp;{id}</i>
    </div>
  );
}

function Example() {

  // The parent component manages the state
  const [ favourites, setFavourites ] = useState([]);

  // When a favourite icon is clicked, get its id
  // and if it's in the state, remove it, otherwise add it
  function handleClick(e) {
    const { id } = e.target.dataset;
    const found = favourites.includes(id);
    if (found) {
      setFavourites(favourites.filter(fav => fav !== id));
    } else {
      setFavourites([...favourites, id]);
    }
  }

  // In this example I'm using a loop to generate the
  // the favourites, checking if the state includes the id
  // (I have to coerce it to a string because that's what
  // the data attributes return, and `i` will always be a number
  // Pass down the handler that the favourite button
  // will use to update the state
  function getFavs() {
    const favs = [];
    for (let i = 0; i < 5; i++) {
      const isFavoured = favourites.includes(i.toString());
      const fav = (
        <Fav
          id={i}
          favoured={isFavoured}
          handleClick={handleClick}
        />
      );
      favs.push(fav);
    }
    return favs;
  }

  return (
    <div>
      {getFavs()}
    </div>
  );
};

ReactDOM.render(
  <Example />,
  document.getElementById('react')
);
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta2/css/all.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>


推荐阅读