React从父组件更新子组件状态:点击Grid随机隐藏单个gridItem
嘿,我来帮你搞定这个需求!下面是基于React的实现方案(如果是Vue/Angular等框架,核心逻辑是相通的):
实现思路
- 父组件
Grid统一维护所有GridItem的状态,用数组存储每个子项的hidden属性 - 点击Grid区域时,先筛选出当前未隐藏的子项,再随机选中其中一个,将其
hidden设为true - 子组件
GridItem接收hidden属性,根据该值控制自身的显示/隐藏
代码示例
父组件:Grid.jsx
import { useState } from 'react'; import GridItem from './GridItem'; const Grid = ({ itemCount = 9 }) => { // 初始化所有子项的hidden状态为false const [items, setItems] = useState( Array.from({ length: itemCount }, () => ({ hidden: false })) ); const handleGridClick = () => { // 先筛选出还没被隐藏的子项索引 const visibleItemIndices = items .map((item, idx) => item.hidden ? null : idx) .filter(idx => idx !== null); // 如果所有子项都已隐藏,就停止操作 if (visibleItemIndices.length === 0) return; // 随机选一个可见子项的索引 const randomIdx = visibleItemIndices[Math.floor(Math.random() * visibleItemIndices.length)]; // 更新状态,将选中的子项hidden设为true setItems(prevItems => { const updatedItems = [...prevItems]; updatedItems[randomIdx] = { ...updatedItems[randomIdx], hidden: true }; return updatedItems; }); }; return ( <div className="grid-container" onClick={handleGridClick} style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: '12px', padding: '24px', cursor: 'pointer', border: '1px solid #eee' }} > {items.map((item, idx) => ( <GridItem key={idx} hidden={item.hidden} itemNumber={idx + 1} /> ))} </div> ); }; export default Grid;
子组件:GridItem.jsx
const GridItem = ({ hidden, itemNumber }) => { return ( <div className="grid-item" style={{ width: '100%', height: '110px', backgroundColor: '#2196F3', borderRadius: '8px', display: hidden ? 'none' : 'flex', alignItems: 'center', justifyContent: 'center', color: '#fff', fontSize: '20px', fontWeight: '500' }} > Item {itemNumber} </div> ); }; export default GridItem;
关键细节说明
- 状态集中管理:把所有子项的状态放在父组件里,能更方便地统一控制和更新,避免子组件状态分散的问题
- 随机逻辑优化:先筛选可见子项再随机,不会出现重复选中已隐藏项的情况
- 事件委托:点击事件绑定在父组件容器上,比给每个子项单独绑事件更高效,尤其当子项数量较多时
- 不可变更新:更新状态时创建新的数组和对象,确保React能正确检测到状态变化并触发重渲染
内容的提问来源于stack exchange,提问作者Aessandro
相关产品推荐
相关产品推荐

