如何在反应中为多个字段制作动态状态?

Posted

技术标签:

【中文标题】如何在反应中为多个字段制作动态状态?【英文标题】: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 个字段的状态 我该怎么做?

【问题讨论】:

【参考方案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'

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

【讨论】:

以上是关于如何在反应中为多个字段制作动态状态?的主要内容,如果未能解决你的问题,请参考以下文章

动态表单 - 如何使用反应钩子更新“onChange”事件中多个表单字段的值?

如何在django中为问题添加多个表单字段类型的选项?

如何在反应中将多个值添加到动态表中?

如何在 routes.js 中为生成的菜单项在通用反应 redux 样板中的边栏中实现动态路由,由 erikras

当应用程序从后台处于活动状态时,如何避免在本机反应中安装组件?

如何在反应原生功能组件中制作动态选择器?