首页 > 解决方案 > React Typescript:使用按钮添加另一行字段以形成

问题描述

我正在构建一个产品销售表单,允许用户添加product namequantityprice. 默认情况下,我希望表单显示 3 行,如果他们想添加另一个产品,会有一个按钮显示“添加产品”,然后会添加另外两个product namequantityprice

我想将限制设置为最多允许 10 行(10 个产品)。

addProductRow(event) { 
    event.preventDefault();
}

<div className={`${styles.flexWrap} ${styles.flexRow}`}>
    <div>
        <label>
            Product Name
        </label>
        <input
            value={this.state.DetailedDescription1}
            onChange={this.handleChangeDetailedDescription1}
            type="text"
            className="phone validate"
            name="Detailed Description"
            maxLength={45}
        />
    </div>  
    <div>
        <label>
            Quanitity
        </label>
        <input
            value={this.state.Quantity1}
            onChange={this.handleChangeQuantity1}
            type="number"
            className="phone validate"
            name="Quantity #1"
            maxLength={9}
            pattern='[0-9]{0,5}'
        />
    </div>
    <div>
        <label>
            Total
        </label>
        <input
            value={this.state.Total1}
            onChange={this.handleChangeTotal1}
            type="number"
            className="phone validate"
            name="Quantity #1"
            maxLength={9}
            pattern='[0-9]{0,5}'
        />
    </div>
</div>

<button onClick={this.addProductRow}>Add New Product</button>
<button onClick={this.removeProductRow}>X</button>

因此,当用户单击“添加新产品”时,将显示一个新行,上面标有上述字段this.state.DetailedDescription2this.handleChangeDetailedDescription1依此类推。

标签: javascriptreactjstypescriptformsreact-native

解决方案


您可以将行数据存储在组件状态(下面的示例使用useState钩子,但根据您的组件结构还有其他方法):

const [rows, setRows] = useState([{ /* row1 data */ }, { /* row 2 data */ }, { /* row3 data */ }])

然后你addProductRow可能看起来像:

addProductRow(){
  if (this.state.rows.length > 9) return 'you cannot add more than 10 rows'
  const rows = JSON.parse(JSON.stringify(this.state.rows)) // make a deep copy since this.state.rows is an array of objects
  rows.push({ /* "new row" data in here */ })
  setRows(rows)
}

然后通过执行渲染行

this.state.rows.map((row, i) => (/* ...all your jsx for a single row goes in here. you can use the index i to reference a specific row of this.state.rows in your change handlers. */))

推荐阅读