如何在React中为多个字段创建动态状态?

13
class Bills extends Component {
constructor(props) {
    super(props)
    this.state = {
        productName: '',
        price: 0,
        quantity: 0,
        noOfProductsField: 0
    }
}
handleChange = name => event => {
    this.setState({
        [name]: event.target.value,
    });
};

createFields = () => {
        const { classes } = this.props;
        let children = []
        for (let i = 0; i < this.state.noOfProductsField; i++) {
            children.push(
                <div>
                    <Select
                        className={classes.textField}
                         value = { this.state[i] }
                    onChange={this.handleChange('productName')}
                        displayEmpty
                        SelectProps={{
                            MenuProps: {
                                className: classes.menu,
                            }
                        }}>
                        <MenuItem value="" disabled>
                            Select Product
                           </MenuItem>
                        {this.state.products.map((option, ind) => (
                            <MenuItem key={ind} value={option.productName}>
                                {option.productName}
                            </MenuItem>
                        ))}
                    </Select>
                    <TextField className={classes.textField} placeholder='Price' type='number' onChange={this.handleChange('price')} />
                    <TextField className={classes.textField} placeholder='Quantity' type='number' onChange={this.handleChange('quantity')} />
                </div>
            )
        }
        return children
    }
}

我有一个函数,它使用for循环创建了3个输入字段:

  • productName(产品名称)
  • price(价格)
  • quantity(数量)

例如,如果循环运行2次,它将创建6个字段,如下图所示:

点击此处查看图片

现在我想为这6个字段分别管理状态,如何做到?

4个回答

6

您需要创建动态表单输入,对吧?那么您可以将产品名称传递给处理程序this.handleChange('productName'),然后可以执行以下操作。在您的情况下,您需要使用计算属性名称以便动态设置状态(就像您已经在做的那样)

handleChange = name => event => {
    //more logic here as per the requirement
    this.setState({
        [name]: event.target.value,
    });
};

或者您可以为产品、价格、数量分别创建单独的onChange处理程序。
handleProductChange = (name) => (evt) => {
    const newProducts = this.state.products.map((product, pidx) => {
      if (name !== product.productName) return product;
      return { ...product, productName: evt.target.value };
    });

    this.setState({ products: newProducts });
}

快速流程:当产品的onChange事件发生时,您可以将产品存储在产品数组(在状态中),当价格更改时,您可以发送产品名称,并将产品与价格和数量进行映射。

此处您可以找到一个使用React的漂亮JS bin副本,实现了您要实现的完全相同的功能。


感谢您的帮助,现在它可以正常工作了。如果您喜欢我的问题,请给我点赞好吗?谢谢! - Huzaifa Ahmed
1
很高兴你解决了它。当然,这是一个好问题。欢迎。 - Shivam

2
你可以给每个输入组件添加name属性,并创建一个处理方法,该方法将名称作为参数获取。
handleInputChange(event) {

  const value = event.target.value;
  const name = event.target.name;

  this.setState({
    [name]: value
  });
}

你可以在 React 文档中阅读更多关于如何处理多个输入的内容。

我们能否使用React Hooks实现相同的目标? - Dulara Malindu
1
@DularaMalindu 是的,但你需要使用 spread operator 来合并属性,因为与类组件的 this.setState() 不同,useState() 钩子不会合并它们。你可以在这里阅读更多信息:https://reactjs.org/docs/hooks-faq.html#should-i-use-one-or-many-state-variables - zb22

2
你可以使用React JS创建动态选择字段。"Original Answer"的翻译是"最初的回答"。
**Code sample:**

const templates = [
    {'id': 1, 'value': 'JavaScript', 'name': 'JavaScript'}, 
    {'id': 2, 'value': 'React', 'name': 'React'},    
    {'id': 3, 'value': 'Angular', 'name': 'Angular'},
    {'id': 4, 'value': 'Node', 'name': 'Node'},
    {'id': 5, 'value': 'Vue', 'name': 'Vue'},
 ]

class Dynamic extends React.Component {
  state={
    selectedTemplates: ""
  }

 onChange = (e) => {
   console.log(e)
   // selected value store into state
    this.setState({ 
      selectedTemplates: e.target.value 
    });
  };

  render() {
    return (
      <div>
        <h2>Dynamic Select(Options):</h2>
        <select className="form-control"
            value={this.state.value}
            onChange={(e) => this.onChange(e.target.value)}
          >
          {
              templates.map(msgTemplate => {
                  return (
                      <option 
                        key={msgTemplate.id} 
                        name={msgTemplate.name} 
                        value={msgTemplate.text}
                       >
                          {msgTemplate.name}
                      </option>
                  )
              })
          }
       </select>
     </div>
    )
  }
}

React.render(<Dynamic />, document.getElementById('app'));

最初的回答:请查看演示 >> codepen

1
简单的状态变量示例如下:
this.state = {
test: 'hello'
}

您可以通过以下方式动态获取状态值:

您可以使用 HTML 保留文本。

let field_name = 'test';
let data = this.state[field_name];

你可以像这样设置状态或替换状态

let field_name = 'test';
this.setState({[field_name]: 'new'}) // test: 'new'

复杂状态替换为
let field_names = {key: 'test'}
this.setState({[field_name.key]: 'ok'}) // test: 'ok'
console.log(this.state[field_name.key]) // test: 'ok'

您可以使用模板字面量,例如:
this.setState({`${field_name.key}`: 'ok'}) // test: 'ok'
console.log(this.state[`${field_name.key}`]) // test: 'ok'

超棒,你得到了解决方案。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接