Skip to content Skip to sidebar Skip to footer

React.js - Create Input Elements From Json Schema

I'm looking for advice on the best way to dynamically create elements from JSON in React using mapping with components. I figure we can have each input type as a separate component

Solution 1:

You need a component that maps over the data and returns the collection of InputTexts. Here I've called it Main.

classMainextendsReact.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` componentreturn data.map((input, i) => {
      return<InputTextkey={i}params={input} />
    });
  }
}

Now you can pick up those params in the component by deconstructing this.props.params and using those variables to fill out the component.

classInputTextextendsReact.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 paramsconst { type, name, classname, placeholder } = this.props.params;

    // Use those properties in the returned component elementsreturn (
      <divclassName={classname}><labelhtmlFor={name}>Test</label><inputonChange={this.changeValue}name={name}type={type}placeholder={placeholder}
        /></div>
    );
  }
}

DEMO

Solution 2:

InputText.jsx

Upon interaction each InputText will raise onChange saying which input field was edited and what is its current value.

import * asReactfrom'react';

exportclassInputTextextendsReact.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 (
      <divclassName={className}><labelhtmlFor={name}>{title}</label><inputplaceholder={placeholder}name={name}type={type}value={value}onChange={this.onChange}
        /></div>
    );
  }
}

Form.jsx

Here we maintain the state of all inputs. The weird reduce is done to initialise the shape of the state with the input names being the object properties.

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

Upon edit this.setState({[name]: value}) the associated property gets updated.

import * asReactfrom'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"
}];

exportclassFormextendsReact.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 (
        <InputTextvalue={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>
    );
  }
}

Solution 3:

Assuming the JSON you want to iterate through is provided in an array you could do something like this. It will create a label and input element for each JSON.

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

Post a Comment for "React.js - Create Input Elements From Json Schema"