如何在一个onClick事件中调用React Hook函数并向Redux Store传值?
问题分析与解决方案
你遇到的核心问题是逗号运算符的误用,这导致你的颜色切换逻辑根本没被执行——逗号运算符会依次计算每个表达式,但只会返回最后一个表达式的结果,所以你的onClick实际上只绑定了passColor函数,前面的颜色切换代码完全被忽略了。
为什么原代码不生效?
比如你写的:
onClick={(changeColor, passColor)}
这里逗号运算符会先获取changeColor的函数引用(但并没有调用它),然后返回passColor作为最终的点击事件处理函数,所以点击按钮时只会触发Redux传值,不会切换T恤颜色。
同样,像(() => setSelected(shirts.grey), passColor)这种写法,箭头函数只是被定义但从未被调用,最终还是只执行passColor。
正确的实现方式
你需要把两个逻辑封装到同一个事件处理函数里,在函数内部依次调用颜色切换和Redux传值方法,并且要正确传递事件对象给passColor:
步骤1:修复单个按钮的点击逻辑
比如白色按钮的onClick可以改成这样:
onClick={(e) => { changeColor(); // 或者直接写setSelected(shirts.white) passColor(e); }}
步骤2:优化代码可维护性
为了避免重复写类似的箭头函数,你可以把颜色和对应的图片映射成数组,循环渲染按钮,让代码更简洁:
修正后的完整代码
import React, { useState } from "react"; import { useSelector, useDispatch } from "react-redux"; import * as actionTypes from "../../store/Actions"; import { CSSTransition } from "react-transition-group"; import "./Shirts.scss"; import white from "../../assets/white.jpg"; import black from "../../assets/black.jpg"; import grey from "../../assets/grey.jpg"; // 统一管理颜色配置,后续新增颜色只需加对象即可 const colorOptions = [ { name: "White", value: "White", image: white, buttonClass: "white-button", textClass: "white-text" }, { name: "Grey", value: "Grey", image: grey, buttonClass: "grey-button", textClass: "grey-text" }, { name: "Black", value: "Black", image: black, buttonClass: "black-button", textClass: "black-text" }, ]; function Shirts() { const [selected, setSelected] = useState(black); // 直接用图片变量更清晰 const selectedPoster = useSelector(state => state.poster); const dispatch = useDispatch(); // 统一的点击处理函数,同时处理颜色切换和Redux传值 const handleColorSelect = (e, targetImage) => { setSelected(targetImage); dispatch({ type: actionTypes.PASS_COLOR, payload: e.currentTarget.value }); }; return ( <div> <div className="shirts"> {/* 注意这里的key要绑定selected,这样图片变化时才会触发过渡动画 */} <CSSTransition in={true} key={selected} appear={true} timeout={300} classNames="fade"> <img alt="T-Shirt" className="shirt" src={selected} /> </CSSTransition> </div> <div> <img className="selected-poster" alt="Poster" src={selectedPoster} /> </div> <div className="color-picker"> {/* 循环渲染颜色按钮,避免重复代码 */} {colorOptions.map((color) => ( <button key={color.value} className={color.buttonClass} value={color.value} onClick={(e) => handleColorSelect(e, color.image)} > <p className={color.textClass}> {color.name.split('').join('<br />')} </p> </button> ))} </div> </div> ); } export default Shirts;
额外注意点
- 原代码里
CSSTransition的key应该用selected而不是shirts,这样当选中的图片变化时,过渡动画才会正确触发。 - 统一颜色配置数组后,代码的可维护性大幅提升,后续新增颜色只需要在数组中添加对应对象,不需要重复编写按钮结构。
内容的提问来源于stack exchange,提问作者Gido
相关产品推荐
相关产品推荐

