I'm trying to dynamically generate input fields for the Rest response. I can't set an state by specifying an unique Id
or unique name
for all the input fields since the name
and id
values are generated dynamically.
Here's my code :
export default class Rest extends Component {
constructor() {
super();
this.state = {
First_Name: "",
data: [],
}
}
handlesubmit = (e) => {
e.preventDefault();
const {First_Name} = this.state;
console.log(this.state)
}
someFunc = (e) => {
const state = this.state
state[e.target.name] = e.target.value;
this.setState(state);
}
componentDidMount() {
fetch('https://facebook.github.io/react-native/movies.json').then((Response) => Response.json()).
then((findresponse) =>
{
console.log(findresponse.movies)
this.setState({
data: findresponse.movies
})
})
}
render()
{
const {First_Name} = this.state;
return(
<div>
<form onSubmit={this.handlesubmit}>
<table className="tat">
<tr><th>name</th><th>year</th></tr>
{
this.state.data.map((dynamicData) =>
<tr className="trow"> <td> {dynamicData.title}
</td> <td> {dynamicData.releaseYear} </td> <td><Input placeholder="First Name..." value={First_Name} name="First_Name" id={dynamicData.releaseYear} onChange={this.someFunc}/></td>
</tr>
) }
</table>
<button type="Submit">submit</button>
</form>
</div>
)
}
}
The output for the following code
The problem is that e.target.name
specifies one particular name all the input fields generated. So If i'm setting <input name={dynamicdata.releaseYear} />
, how will I set the state for all the input fields with dynamically generated names.
Thank you...
You are trying to directly mutate your state:
someFunc = (e) => {
const state = this.state
state[e.target.name] = e.target.value;
this.setState(state);
}
You could do:
someFunc = (e) => {
const newState = JSON.parse(JSON.stringify(this.state));
newState[e.target.name] = e.target.value;
this.setState(newState);
}
Updating:
changing e.target.name
to e.target.id
, so that each key id
will store the value of the corresponding input field.
someFunc = (e) => {
const newState = JSON.parse(JSON.stringify(this.state));
newState[e.target.id] = e.target.value;
this.setState(newState);
}
Oh, i have faced this issue before. Update your form
to
<form onSubmit={(e) => this.handlesubmit(e)}>
<table className="tat">
<tr><th>name</th><th>year</th></tr>
{
this.state.data.map((dynamicData) =>
(<tr className="trow"> <td> {dynamicData.title}
</td> <td> {dynamicData.releaseYear} </td> <td><Input placeholder="First Name..." value={First_Name} name="First_Name" id={dynamicData.releaseYear} onChange={(e) => this.someFunc(e)}/></td>
</tr>)
) }
</table>
<button type="Submit">submit</button>
</form>
Change onSubmit
and onChange
functions to :
onSubmit={(e) => this.handlesubmit(e)}
and
onChange={(e) => this.someFunc(e)}
respectively.
The issue is because the scope of this
, When you call the onSubmit
or onChange
your way, this
is the DOM element not the React component, hence this
doesn't have access to React state
properties.
UPDATE: based on your comments
Change the functions as below
onChange={e => this.someFunc(e, dynamicData.releaseYear)} // because dynamicData.releaseYear is the ID
Next
someFunc = (e, id) => {
const state = this.state
state[id] = e.target.value; // or state["prefix_"+id] = e.target.value;
this.setState(state);
}
OR if you want to use names
this.state.data.map((dynamicData, index) =>
(<tr className="trow"> <td> {dynamicData.title}
</td> <td> {dynamicData.releaseYear} </td> <td><Input placeholder="First Name..." value={First_Name} name="First_Name" id={dynamicData.releaseYear} onChange={e => this.someFunc(e, index)}/></td>
</tr>)
) }
someFunc = (e, index) => {
const state = this.state
state[e.target.name +"_"+index] = e.target.value;
this.setState(state);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.