user9348468
user9348468

Reputation:

update values in react form input fields

I am new to react and I can fetch the result from form input fields. Now I need to update those values and submit to the backend. I am struggling to find a way to pass all the input field values at once.

constructor(props) {
    super(props);
    this.state = {
        items: [],
        isLoaded: false,
        data: this.props.location.data
    };
}

render() {
    return (
        <div>
            <h2>Update Your Profile</h2>
            {items.map(item => (
                <Form key={item.uId} onSubmit={this.handleSubmit}>
                        <label>User Name</label>
                        <input type="text" defaultValue={item.userName}></input>
                        <label>Email address</label>
                        <input type="email" defaultValue={item.email}></input>
                    </div>
                    <button type="submit" >Update</button>
                </Form>
            ))}
        </div>
    );
}

handleSubmit = (e) => {
    e.preventDefault();
    axios.put('http://localhost:3000/api/user/' + this.state.data, this.state.items).then(response => {
        //
    });
};

My API call looks like this:

app.put('/api/user/:userId', (req, res, err) => {
    User.update(
        { userName: req.body.userName, email: req.body.email },
        {
            where: {
                userId: req.params.userId
            }
        }
    ).then(function (rowsUpdated) {
        res.json(rowsUpdated)
    }).catch(err);
});

How can I modify this code to set a value for this.state.items with all the updated fields values and submit it?

Upvotes: 1

Views: 22856

Answers (1)

Alexander Staroselsky
Alexander Staroselsky

Reputation: 38757

I'd recommend to create a new component to wrap around the <Form /> and move the submit/change event handling to that component for each item. This would allow you to be able to extract individual email/userName for any given <Form /> to send as a PUT to your API endpoint as well as handle the respective input value changes.

Parent Component:

class Parent extends Component {
  constructor() {
    super();
    this.state = {
      name: 'React',
      items: [
        { uId: 1, email: '[email protected]', userName: 'bar' },
        { uId: 2, email: '[email protected]', userName: 'foobar' }
      ]
    };
  }

  render() {
    return (
      <div>
        {this.state.items.map(item => 
          <MyForm key={item.uId} item={item} data={this.props.location.data} />)}
      </div>
    );
  }
}

Child/Form Component:

import React, { Component } from 'react';

class MyForm extends Component {
  constructor(props) {
    super(props);

    this.state = {
      email: this.props.item.email,
      userName: this.props.item.userName
    };

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  // https://reactjs.org/docs/forms.html#handling-multiple-inputs
  handleChange(e) {
    const { target}  = event;
    const value = target.type === 'checkbox' ? target.checked : target.value;
    const { name }  = target;

    this.setState({ [name]: value });
  }

  handleSubmit(e) {
    e.preventDefault();

    const { email, userName } = this.state;
    const body = { email, userName };
    const json = JSON.stringify(body);
    console.log(json);

    // axios.put('http://localhost:3000/api/user/' + this.props.data, json).then(response => {});
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>User Name</label>
        <input type="text" defaultValue={this.state.userName}></input>
        <label>Email address</label>
        <input type="email" defaultValue={this.state.email}></input>

        <button type="submit" >Update</button>
      </form>
    );
  }
}

export default MyForm;

Here is an example in action.

Hopefully that helps!

Upvotes: 2

Related Questions