You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Redux Toolkit实现按钮独立控制及解决check[id] undefined问题

问题根源与解决方案

核心问题

  1. 你的Redux状态checkValue.isChecked是单个布尔值,所有按钮共用同一个状态,导致点击任意按钮时所有按钮都会触发active类
  2. console.log(check[id])输出undefined,是因为check是布尔值(不是对象/数组),根本不存在id属性
  3. 需求是记录单个选中按钮的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>
  );
}

关键修改点说明

  1. Redux状态调整:用selectedId记录当前选中的按钮ID,替代全局布尔值,实现单个按钮的独立状态控制
  2. 组件逻辑简化:去掉无用的itemValue状态和toggle函数,直接在点击时dispatch选中的ID
  3. className修正:原来的字符串相加写法会导致语法错误,改用ES6模板字符串实现条件类名拼接
  4. SelectItem组件优化:不再在子组件中订阅Redux状态,而是通过props传递isActive状态,减少不必要的订阅

内容的提问来源于stack exchange,提问作者jigoooo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 07:54:17