简体   繁体   中英

Setting states for dynamic input fields in react

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM