如何在React中实现点击按钮复制带新ID的Div块(不使用jQuery)
如何在React中不使用jQuery实现点击按钮复制Div块并修改ID和数据?
嘿,这完全可行!而且在React里实现这个功能的思路和jQuery直接操作DOM的方式截然不同——React是状态驱动UI,咱们不需要手动去复制或修改DOM元素,而是通过维护组件状态,让React自动帮我们渲染出对应的区块。
核心思路
React的核心是「状态变化→UI自动更新」,所以我们只需要:
- 用一个状态来记录所有需要渲染的区块信息(比如一个数组,或者一个计数)
- 点击按钮时更新这个状态
- 在
render(类组件)或者组件主体(函数组件)里,根据状态循环生成对应的区块
类组件实现示例
如果你还在使用类组件,可以这样写:
class ExpenseBlockContainer extends React.Component { constructor(props) { super(props); // 初始化状态:用数组存储区块,初始有1个区块 this.state = { blocks: [0] // 这里存的是每个区块的索引,你也可以存更复杂的数据 }; // 绑定this上下文 this.addRow = this.addRow.bind(this); } addRow() { // 更新状态:往数组里添加新的索引值 this.setState(prevState => ({ blocks: [...prevState.blocks, prevState.blocks.length] })); } render() { return ( <div> {/* 循环生成所有区块 */} {this.state.blocks.map(blockIndex => ( <div key={blockIndex} // 必须加key,帮助React识别每个元素 className="expense-block" id={`expense-block-${blockIndex}`} data-block={blockIndex} > {/* 这里可以放区块里的内容 */} </div> ))} {/* 添加按钮 */} <button type="button" className="btn btn-primary custom-add-button add-row" onClick={this.addRow} > <i className="fas fa-plus"></i> 添加区块 </button> </div> ); } }
函数组件(React Hooks)实现示例
现在更推荐用函数组件+Hooks来写,代码更简洁:
import { useState } from 'react'; function ExpenseBlockContainer() { // 用useState初始化状态,blocks是存储区块索引的数组 const [blocks, setBlocks] = useState([0]); const addRow = () => { // 更新状态:生成新数组,添加新的索引 setBlocks(prevBlocks => [...prevBlocks, prevBlocks.length]); }; return ( <div> {blocks.map(blockIndex => ( <div key={blockIndex} className="expense-block" id={`expense-block-${blockIndex}`} data-block={blockIndex} > {/* 区块内容 */} </div> ))} <button type="button" className="btn btn-primary custom-add-button add-row" onClick={addRow} > <i className="fas fa-plus"></i> 添加区块 </button> </div> ); }
关键说明
- key属性:循环渲染元素时必须加
key,它帮助React高效地识别每个元素的变化,避免不必要的重渲染。这里我们用区块的索引当key是没问题的,因为每个索引都是唯一的。 - 状态更新的正确姿势:当新状态依赖于旧状态时,一定要用「函数式更新」(比如
setState(prevState => ...)或者setBlocks(prevBlocks => ...)),这样能确保拿到的是最新的状态值。 - 扩展性:如果以后每个区块需要存储自定义数据(比如输入框的值),你可以把
blocks数组改成存储对象的数组,比如[{id: 0, value: ''}, {id:1, value: ''}],这样每个区块的状态都能独立管理。
内容的提问来源于stack exchange,提问作者Dominykas55
相关产品推荐
相关产品推荐

