【问题标题】:How to make dynamic state for multiple fields in react?如何在反应中为多个字段制作动态状态?
【发布时间】:2019-04-20 08:05:11
【问题描述】:
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 个输入字段

  • 产品名称
  • 价格
  • 数量

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

所以现在我想以不同的方式管理所有 6 个字段的状态 我该怎么做?

【问题讨论】:

    标签: javascript reactjs jsx


    【解决方案1】:

    您需要创建动态表单输入吗?因此,您可以将产品名称传递给处理程序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 发生时,您可以将产品存储在 procucts 数组中(处于状态),当价格发生变化时,您可以将产品名称连同它一起发送并映射产品价格和数量。

    Here 你可以使用 React 找到一个不错的 JS bin 副本,与你想要实现的完全一样。

    【讨论】:

    • 感谢您帮助它正常工作。如果你喜欢我的问题,你可以投票吗?谢谢
    • 很高兴你能成功。当然,这是一个很好的问题。欢迎
    【解决方案2】:

    您可以为每个输入组件添加name 属性,并创建一个处理程序方法,该方法将名称作为参数。

    handleInputChange(event) {
    
      const value = event.target.value;
      const name = event.target.name;
    
      this.setState({
        [name]: value
      });
    }
    

    您可以在 React 文档中阅读有关 how to handle multiple inputs 的更多信息。

    【讨论】:

    • 我们可以用 react hooks 实现同样的目标吗?
    • @DularaMalindu 是的,但是您需要使用spread operator 来合并属性,因为与类组件的this.setState() 不同,useState() 挂钩不会合并它们。你可以在这里阅读更多信息:reactjs.org/docs/…
    【解决方案3】:

    您可以使用 react js 创建动态选择字段

    **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

    【讨论】:

      【解决方案4】:

      状态变量的简单示例如下所示:

      this.state = {
      test: 'hello'
      }
      

      您可以通过

      动态获取状态值
      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'
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-12-06
        • 1970-01-01
        • 1970-01-01
        • 2020-09-23
        • 1970-01-01
        • 1970-01-01
        • 2019-07-01
        相关资源
        最近更新 更多