如何用React-Redux实现点击主分类显示/隐藏对应子分类
实现分类展开/收起的Redux逻辑方案
1. 更新初始状态(initialState)
在初始状态中新增字段跟踪当前展开的主分类ID,默认值设为null(表示所有子分类默认收起):
const initialState = { data: [], status: STATUSES.IDLE, expandedCategoryId: null // 新增:记录当前展开的主分类ID };
2. 添加Redux Action与Reducer
在adsSlice的reducers中新增处理分类展开/收起的逻辑:
export const adsSlice = createSlice({ name: "ads_category", initialState, reducers: { // 新增:处理分类展开/收起 toggleCategory: (state, action) => { const categoryId = action.payload; // 点击已展开的分类则收起,否则展开目标分类并自动收起其他 state.expandedCategoryId = state.expandedCategoryId === categoryId ? null : categoryId; } // 保留原有注释或已存在的reducers // setProducts(state, action) { // state.data = action.payload; // }, // setStatus(state, action) { // state.status = action.payload; // }, }, extraReducers: (builder) => { builder .addCase(fetchProducts.pending, (state, action) => { state.status = STATUSES.LOADING; }) .addCase(fetchProducts.fulfilled, (state, action) => { state.data = action.payload; state.status = STATUSES.IDLE; }) .addCase(fetchProducts.rejected, (state, action) => { state.status = STATUSES.ERROR; }); }, }); // 导出新增的action供组件调用 export const { toggleCategory } = adsSlice.actions;
3. 修改页面组件逻辑
在PostAds组件中引入toggleCategory action,添加点击事件并控制子分类显示:
// 引入新增的action import { toggleCategory } from './path-to-your-adsSlice'; const PostAds = () => { const dispatch = useDispatch(); const { data, status, expandedCategoryId } = useSelector(state=>state.ads); useEffect(() => { dispatch(fetchProducts()); }, []); // 渲染分类的示例逻辑 const renderCategories = () => { if (status === STATUSES.LOADING) return <div>加载中...</div>; if (status === STATUSES.ERROR) return <div>加载失败</div>; return data.map(mainCategory => ( <div key={mainCategory.id} className="main-category"> {/* 主分类标题,绑定点击事件 */} <h3 onClick={() => dispatch(toggleCategory(mainCategory.id))}> {mainCategory.name} {/* 可选:添加展开/收起状态图标 */} {expandedCategoryId === mainCategory.id ? '▼' : '▶'} </h3> {/* 根据expandedCategoryId判断是否渲染子分类 */} {expandedCategoryId === mainCategory.id && ( <div className="sub-categories"> {mainCategory.subCategories.map(sub => ( <div key={sub.id} className="sub-category"> {sub.name} </div> ))} </div> )} </div> )); }; return ( <div className="post-ads-container"> {renderCategories()} </div> ) }
核心逻辑说明
- 点击主分类时,触发
toggleCategoryaction并传入当前主分类ID - Redux reducer中做判断:若点击的是已展开的分类,则收起(设
expandedCategoryId为null);否则展开目标分类(更新expandedCategoryId为当前ID),自动实现“仅展开一个分类”的效果 - 组件通过对比
expandedCategoryId与当前主分类ID,控制对应子分类的显示/隐藏
内容的提问来源于stack exchange,提问作者hawaj
相关产品推荐
相关产品推荐

