【问题标题】:React.js - Create input elements from JSON schemaReact.js - 从 JSON 模式创建输入元素
【发布时间】:2018-05-24 05:26:46
【问题描述】:

我正在寻找有关在 React 中使用组件映射从 JSON 动态创建元素的最佳方法的建议。

我认为我们可以将每个输入类型作为一个单独的组件类并构造传入props 的元素并绑定更改。

例如JSON:

    {
        "type": "text",
        "name": "FirstName",                    
        "class": "text",
        "placeholder": "Enter first name"
    },
    {
        "type": "text",
        "name": "Surname",                  
        "class": "text",
        "placeholder": "Enter surname"
    },

反应:

class InputText extends React.Component {
  constructor(props) {
    super(props);
    this.changeValue = this.changeValue.bind(this);
  }

  render() {
    return (
      <div className={className}>
        <label htmlFor={this.props.name}>{this.props.title}</label>
        <input
          onChange={this.changeValue}
          name={this.props.name}
          type={this.props.type}
          value={this.props.value}
        />
      </div>
    );
  }
}

关于迭代(和验证)JSON 中每个项目的最佳方法有什么建议吗?我在正确的轨道上吗?谢谢!

【问题讨论】:

    标签: javascript json reactjs


    【解决方案1】:

    您需要一个组件,它可以maps 覆盖数据并返回InputTexts 的集合。这里我称之为Main

    class Main extends React.Component {
      render() {
    
        // Map over the data and return the completed component
        // On each iteration pass in the object data as `params`.
        // You can deconstruct this in the `InputText` component
        return data.map((input, i) => {
          return <InputText key={i} params={input} />
        });
      }
    }
    

    现在您可以通过解构this.props.params 并使用这些变量填充组件来获取组件中的这些参数。

    class InputText extends React.Component {
    
      constructor(props) {
        super(props);
        this.changeValue = this.changeValue.bind(this);
      }
    
      changeValue() {
        console.log('Placeholder to prevent bug');
      }
    
      render() {
    
       // Use destructuring to grab the individual properties from params
       const { type, name, classname, placeholder } = this.props.params;
    
        // Use those properties in the returned component elements
        return (
          <div className={classname}>
            <label htmlFor={name}>Test</label>
            <input
              onChange={this.changeValue}
              name={name}
              type={type}
              placeholder={placeholder}
            />
          </div>
        );
      }
    }
    

    DEMO

    【讨论】:

    • 一个简单而优雅的解决方案,这对我来说很有意义。非常感谢您的回答。
    【解决方案2】:

    InputText.jsx

    在交互时,每个InputText 都会引发onChange,说明编辑了哪个输入字段及其当前值。

    import * as React from 'react';
    
    export class InputText extends React.Component {
      onChange = (e) => {
        const {onChange, name} = this.props;
        const {value} = e.target;
        if (onChange) {
          onChange(name, value);
        }
      }
    
      render() {
        const {name, title, type, placeholder, className, value} = this.props;
        return (
          <div className={className}>
            <label htmlFor={name}>{title}</label>
            <input
              placeholder={placeholder}
              name={name}
              type={type}
              value={value}
              onChange={this.onChange}
            />
          </div>
        );
      }
    }
    

    Form.jsx

    这里我们维护所有输入的状态。奇怪的reduce 用于初始化状态的形状,输入名称是对象属性。

    // initial state
    {
      "FirstName": "",
      "Surname": ""
    }
    

    在编辑 this.setState({[name]: value}) 时,关联的属性会更新。

    import * as React from 'react';
    import { InputText } from './InputText';
    
    const inputs = [{
      "type": "text",
      "title": "some title",
      "name": "FirstName",
      "class": "text",
      "placeholder": "Enter first name"
    }, {
      "type": "text",
      "title": "some other title",
      "name": "Surname",
      "class": "text",
      "placeholder": "Enter surname"
    }];
    
    export class Form extends React.Component {
      constructor(props) {
        super(props);
        this.state = inputs.reduce((acc, input) => {
          return {...acc, [input.name]: ''};
        }, {})
      }
    
      onChange = (name, value) => {
        this.setState({[name]: value});
      }
    
      render() {
        const list = inputs.map(input => {
          return (
            <InputText
              value={this.state[input.name]}
              key={input.name}
              type={input.type}
              name={input.name}
              title={input.title}
              className={input.class}
              placeholder={input.placeholder}
              onChange={this.onChange}
          />
          );
        });
    
        return (
          <form>
            {list}
          </form>
        );
      }
    }
    

    【讨论】:

      【解决方案3】:

      假设您要迭代的 JSON 是在一个数组中提供的,您可以执行类似的操作。它将为每个 JSON 创建一个标签和输入元素。

      render() {
        return (
          <div className={className}>
            {
            this.props.yourArray.map(value=>(
              <label htmlFor={value.name}>{value.title}</label>
              <input
                onChange={this.changeValue}
                name={value.name}
                type={value.type}
                value={value.value}
              />
            ))
            }
          </div>
        );
      }
      

      【讨论】:

        猜你喜欢
        • 2013-09-24
        • 2016-06-11
        • 1970-01-01
        • 2015-08-12
        • 1970-01-01
        • 2019-09-23
        • 2022-10-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多