【问题标题】:Add A New Item to React State from outside Entry Point从入口点外部向 React State 添加新项目
【发布时间】:2020-05-10 20:19:56
【问题描述】:

我有两个具有相同类和不同 ID 的按钮。我希望在单击按钮时将新商品添加到购物车中。

<body>
    <div id="account"></div>
    <button class="add-to-cart" id="1234">
        Add to cart
    </button>
    <button class="add-to-cart" id="1534">
        Add to cart 2
    </button>
    <script src="js/index.js"></script>
</body>

react 组件的状态管理部分看起来像

    const [cart, setCart] = useState([])

    useEffect(() => {
        const addToCartButtons = document.querySelectorAll('.add-to-cart')

        addToCartButtons.forEach(button => {
            button.addEventListener('click', e => {
                setCart(() => [...cart, button.id])
            })
        })
    }, [])

每次单击按钮时,都会形成一个新数组,其中仅包含一个新值,而不是展开购物车的先前值并添加新值。

【问题讨论】:

  • 为什么要在 React 应用程序之外渲染按钮?
  • @JMadeline 因为我想响应只处理应用程序的购物车部分,并在 vanilla js 中有电子商务产品的详细页面

标签: javascript reactjs react-hooks


【解决方案1】:

来自您的代码

const [cart, setCart] = useState([])

useEffect(() => {
    const addToCartButtons = document.querySelectorAll('.add-to-cart')

    addToCartButtons.forEach(button => {
        button.addEventListener('click', e => {
            setCart(() => [...cart, button.id])
        })
    })
}, [])

您可以看到setCart(() =&gt; [...cart, button.id]) 中的cart 始终是初始购物车,因为useEffect 的依赖列表中没有购物车。

然后,您只想使用componentDidMount,因此您无法将购物车添加到依赖项列表中。

尝试通过引用使用cart 变量

例如

const [cart, setCart] = useState([])

const cartRef = useRef() // <--- import {useRef} from 'react'
cartRef.current = cart

useEffect(() => {
    const addToCartButtons = document.querySelectorAll('.add-to-cart')
    addToCartButtons.forEach(button => {
        button.addEventListener('click', e => {
            const currentCart = cartRef.current // <--- read cart variable using reference
            setCart(() => [...currentCart, button.id])
        })
    })
}, [])

【讨论】:

  • 添加购物车到依赖数组解决了这个问题,非常感谢!
  • 如果你将cart添加到依赖数组中,当你使用函数setCart时你会执行addEventListener,这应该是你系统的一个bug。
  • 哦,好吧,所以首选其他解决方案,为什么? addEventListener 已经在组件渲染后监听点击事件。
  • useEffect 将在依赖列表中的某些数据发生变化时触发输入函数,并且 addEventListener 可以使用任意次数来处理具有更多事件侦听器的事件。总之,setCart 将改变购物车的值。当购物车值发生变化时,会触发 useEffect 中的函数。当函数被触发时,它将新的 eventListeners 添加到同一元素。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-25
  • 1970-01-01
  • 2018-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多