问题
I have the below json data and the react code to populate the data dynamically
var DATA = [{"processList":
[{"processId":"1","processName":"Process1","htmlControlType":"radio","cssClassName":"radio"},
{"processId":"2","processName":"Process2","htmlControlType":"radio","cssClassName":"radio"}],
"processIndexList":
[{"processId":"1","indexId":"1","indexDesc":"First Name","htmlControlType":"textbox","cssClassName":"form-control"},{"indexId":"2","indexDesc":"Last Name","htmlControlType":"textbox","cssClassName":"form-control"}]}];
renderProcessList: function () {
const data = DATA;
return data[0].processList.map(group => {
return <div className={group.cssClassName}>
<label><input type={group.htmlControlType} name="processOptions"/>{group.processName}</label>
</div>
});
},
renderProcessData: function () {
const data = DATA;
return data[0].processIndexList.map(group => {
return <div>
<label>{group.indexDesc}</label>
<input type={group.htmlControlType} className={group.cssClassName} placeholder=""/>
<br/>
</div>
});
},
As of now the form is getting displayed based on the json data, but i want to display the form based on the user selection in the process list ex: If the user select the Process1 radio the the First Name text box needs to be displayed below the radio and the user selects the process2 then Last Name text box needs to be displyed.
Can anyone tell me how to do it in reactjs?
回答1:
To achieve the task, you have to implement the next three steps:
- Handle radio input click.
- Store the selected process ID in the state.
- Display process list items, based on the selected ID (a.k.a. filtering).
Please note that you missed to add processId property in processIndexList[1] object.
Also please consider that in the example below I'm using basic filtering in renderProcessData().
I implemented the example in ES5, ES6 because of question's author request. Keep in mind that in the both examples I'm using JSX, so you need a compiler tool (Babel for example). Once you use a compiler, then you can use latest JS features. Please revise your choise of using ES5.
ES6
var DATA = [{
"processList": [{
"processId": "1",
"processName": "Process1",
"htmlControlType": "radio",
"cssClassName": "radio"
},
{
"processId": "2",
"processName": "Process2",
"htmlControlType": "radio",
"cssClassName": "radio"
}
],
"processIndexList": [{
"processId": "1",
"indexId": "1",
"indexDesc": "First Name",
"htmlControlType": "textbox",
"cssClassName": "form-control"
}, {
"processId": "2",
"indexId": "2",
"indexDesc": "Last Name",
"htmlControlType": "textbox",
"cssClassName": "form-control"
}]
}];
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
selectedProcessID: null
};
}
setProcessID(e) {
this.setState({
selectedProcessID: e.target.value
});
}
renderProcessList() {
const data = DATA;
return data[0].processList.map( group => {
return <div className={group.cssClassName}>
<label><input
value={group.processId}
onClick={this.setProcessID.bind(this)}
type={group.htmlControlType}
name="processOptions"/>{group.processName}</label>
</div>
});
}
renderProcessData() {
// Display process data, only if there is already
// selected process ID
if ( ! this.state.selectedProcessID) return;
const data = DATA;
return data[0].processIndexList.map( group => {
// Display process list items for the selected process ID.
// The filtering can be implemented performance better with a library (lodash for example).
// Current implementation is enough for the SO demo.
if (group.processId !== this.state.selectedProcessID) return;
return <div>
<label>{group.indexDesc}</label>
<input type={group.htmlControlType} className={group.cssClassName} placeholder=""/>
<br/>
</div>
});
}
render() {
return <div>
{this.renderProcessList()}
{this.renderProcessData()}
</div>
}
}
ReactDOM.render(<App />, document.getElementById('container'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container"></div>
ES5
var DATA = [{
"processList": [{
"processId": "1",
"processName": "Process1",
"htmlControlType": "radio",
"cssClassName": "radio"
},
{
"processId": "2",
"processName": "Process2",
"htmlControlType": "radio",
"cssClassName": "radio"
}
],
"processIndexList": [{
"processId": "1",
"indexId": "1",
"indexDesc": "First Name",
"htmlControlType": "textbox",
"cssClassName": "form-control"
}, {
"processId": "2",
"indexId": "2",
"indexDesc": "Last Name",
"htmlControlType": "textbox",
"cssClassName": "form-control"
}]
}];
var App = React.createClass({
getInitialState() {
return {
selectedProcessID: null
}
},
setProcessID: function(e) {
this.setState({
selectedProcessID: e.target.value
});
},
renderProcessList: function() {
const data = DATA;
return data[0].processList.map( group => {
return <div className={group.cssClassName}>
<label><input
value={group.processId}
onClick={this.setProcessID.bind(this)}
type={group.htmlControlType}
name="processOptions"/>{group.processName}</label>
</div>
});
},
renderProcessData: function() {
// Display process data, only if there is already
// selected process ID
if ( ! this.state.selectedProcessID) return;
const data = DATA;
return data[0].processIndexList.map( group => {
// Display process list items for the selected process ID.
// The filtering can be implemented performance better with a library (lodash for example).
// Current implementation is enough for the SO demo.
if (group.processId !== this.state.selectedProcessID) return;
return <div>
<label>{group.indexDesc}</label>
<input type={group.htmlControlType} className={group.cssClassName} placeholder=""/>
<br/>
</div>
});
},
render: function() {
return <div>
{this.renderProcessList()}
{this.renderProcessData()}
</div>
}
});
ReactDOM.render(<App />, document.getElementById('container'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container"></div>
来源:https://stackoverflow.com/questions/42642675/creating-dynamic-html-using-json-data-in-reactjs