如何用Redux Toolkit实现按钮独立控制及解决check[id] undefined问题
问题根源与解决方案
核心问题
- 你的Redux状态
checkValue.isChecked是单个布尔值,所有按钮共用同一个状态,导致点击任意按钮时所有按钮都会触发active类 console.log(check[id])输出undefined,是因为check是布尔值(不是对象/数组),根本不存在id属性- 需求是记录单个选中按钮的ID,而非全局的选中状态
第一步:修改Redux Store
把checkValue切片改成记录选中的ID,而非单个布尔值:
let checkValue = createSlice({ name: "checkValue", initialState: { selectedId: null, // 初始无选中项 }, reducers: { setSelectedId: (state, action) => { // 如果点击的是已选中的ID,取消选中;否则设置为当前ID state.selectedId = state.selectedId === action.payload ? null : action.payload; }, }, }); export default configureStore({ reducer: { characters: characters.reducer, areas: areas.reducer, checkValue: checkValue.reducer, }, }); export let { setSelectedId } = checkValue.actions;
第二步:修改Select组件
调整组件逻辑,使用选中ID来控制单个按钮的active类:
function Select() { const [characterFlip, setCharacterFlip] = useState(false); const [areaFlip, setAreaFlip] = useState(false); const dispatch = useDispatch(); const characters = useSelector(state => state.characters); const areas = useSelector(state => state.areas); const selectedId = useSelector(state => state.checkValue.selectedId); const characterExpanded = () => { setCharacterFlip(prev => !prev); }; const characterBtn = (id) => { dispatch(setSelectedId(id)); // 点击时把当前按钮ID传给Redux }; return ( <section className="select"> <div className="select__group character"> <div className="select__header" onClick={characterExpanded}> <i className={`fa fa-solid fa-angle-${characterFlip ? "up" : "down"}`} ></i> <span className="select__title">어떤 빵?</span> </div> {/* 修正className拼接方式,用模板字符串 */} <ul className={`select__list ${characterFlip ? "show" : "hide"}`}> {characters.map(character => { return ( <SelectItem selectedData={character} selectedBtn={characterBtn} name={character.name} isActive={selectedId === character.id} // 传递当前按钮是否激活的状态 key={character.id} /> ); })} </ul> </div> </section> ); } function SelectItem(props) { return ( <li className="select__item"> {/* 用模板字符串拼接className,根据isActive判断是否加active类 */} <button className={`item__btn ${props.isActive ? "active" : ""}`} onClick={() => { props.selectedBtn(props.selectedData.id); }} > {props.name} </button> </li> ); }
关键修改点说明
- Redux状态调整:用
selectedId记录当前选中的按钮ID,替代全局布尔值,实现单个按钮的独立状态控制 - 组件逻辑简化:去掉无用的
itemValue状态和toggle函数,直接在点击时dispatch选中的ID - className修正:原来的字符串相加写法会导致语法错误,改用ES6模板字符串实现条件类名拼接
- SelectItem组件优化:不再在子组件中订阅Redux状态,而是通过props传递
isActive状态,减少不必要的订阅
内容的提问来源于stack exchange,提问作者jigoooo
相关产品推荐
相关产品推荐

