admin管理员组文章数量:1022804
I'm looking for advice on the best way to dynamically create elements from JSON in React using mapping with ponents.
I figure we can have each input type as a separate ponent class and construct the element passing in props
and bind the changes.
E.g. the JSON:
{
"type": "text",
"name": "FirstName",
"class": "text",
"placeholder": "Enter first name"
},
{
"type": "text",
"name": "Surname",
"class": "text",
"placeholder": "Enter surname"
},
React:
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>
);
}
}
Any advice on the best way to iterate through (and validate) each item in the JSON? Am I on the right track here? Thanks!
I'm looking for advice on the best way to dynamically create elements from JSON in React using mapping with ponents.
I figure we can have each input type as a separate ponent class and construct the element passing in props
and bind the changes.
E.g. the JSON:
{
"type": "text",
"name": "FirstName",
"class": "text",
"placeholder": "Enter first name"
},
{
"type": "text",
"name": "Surname",
"class": "text",
"placeholder": "Enter surname"
},
React:
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>
);
}
}
Any advice on the best way to iterate through (and validate) each item in the JSON? Am I on the right track here? Thanks!
Share Improve this question edited Dec 10, 2017 at 17:39 Paul Redmond asked Dec 10, 2017 at 15:19 Paul RedmondPaul Redmond 3,2964 gold badges35 silver badges53 bronze badges3 Answers
Reset to default 2You need a ponent that map
s over the data and returns the collection of InputText
s. Here I've called it Main
.
class Main extends React.Component {
render() {
// Map over the data and return the pleted ponent
// On each iteration pass in the object data as `params`.
// You can deconstruct this in the `InputText` ponent
return data.map((input, i) => {
return <InputText key={i} params={input} />
});
}
}
Now you can pick up those params in the ponent by deconstructing this.props.params
and using those variables to fill out the ponent.
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 ponent elements
return (
<div className={classname}>
<label htmlFor={name}>Test</label>
<input
onChange={this.changeValue}
name={name}
type={type}
placeholder={placeholder}
/>
</div>
);
}
}
DEMO
InputText.jsx
Upon interaction each InputText
will raise onChange
saying which input field was edited and what is its current value.
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
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 * 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>
);
}
}
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 (
<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>
);
}
I'm looking for advice on the best way to dynamically create elements from JSON in React using mapping with ponents.
I figure we can have each input type as a separate ponent class and construct the element passing in props
and bind the changes.
E.g. the JSON:
{
"type": "text",
"name": "FirstName",
"class": "text",
"placeholder": "Enter first name"
},
{
"type": "text",
"name": "Surname",
"class": "text",
"placeholder": "Enter surname"
},
React:
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>
);
}
}
Any advice on the best way to iterate through (and validate) each item in the JSON? Am I on the right track here? Thanks!
I'm looking for advice on the best way to dynamically create elements from JSON in React using mapping with ponents.
I figure we can have each input type as a separate ponent class and construct the element passing in props
and bind the changes.
E.g. the JSON:
{
"type": "text",
"name": "FirstName",
"class": "text",
"placeholder": "Enter first name"
},
{
"type": "text",
"name": "Surname",
"class": "text",
"placeholder": "Enter surname"
},
React:
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>
);
}
}
Any advice on the best way to iterate through (and validate) each item in the JSON? Am I on the right track here? Thanks!
Share Improve this question edited Dec 10, 2017 at 17:39 Paul Redmond asked Dec 10, 2017 at 15:19 Paul RedmondPaul Redmond 3,2964 gold badges35 silver badges53 bronze badges3 Answers
Reset to default 2You need a ponent that map
s over the data and returns the collection of InputText
s. Here I've called it Main
.
class Main extends React.Component {
render() {
// Map over the data and return the pleted ponent
// On each iteration pass in the object data as `params`.
// You can deconstruct this in the `InputText` ponent
return data.map((input, i) => {
return <InputText key={i} params={input} />
});
}
}
Now you can pick up those params in the ponent by deconstructing this.props.params
and using those variables to fill out the ponent.
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 ponent elements
return (
<div className={classname}>
<label htmlFor={name}>Test</label>
<input
onChange={this.changeValue}
name={name}
type={type}
placeholder={placeholder}
/>
</div>
);
}
}
DEMO
InputText.jsx
Upon interaction each InputText
will raise onChange
saying which input field was edited and what is its current value.
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
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 * 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>
);
}
}
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 (
<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>
);
}
本文标签: javascriptReactjsCreate input elements from JSON schemaStack Overflow
版权声明:本文标题:javascript - React.js - Create input elements from JSON schema - Stack Overflow 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/questions/1745548992a2155530.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论