0

I am creating react app just for training purpose. I am not able to set value on form submit button. If I start typing the values are getting store in name and price but when I click submit button it does not set name and price in formData.

If I try to set values in formData.

onChange={(e) => this.setState({formData:{
price: e.target.value
})}

like above then I can not type input field.

You can check I used console to check what is happening.

import React from 'react';
import { Button, Form, Icon, Modal } from 'semantic-ui-react';

export default class ProductForm extends React.Component {

constructor(props) {
    super(props);
    this.state = {
        showCreateForm: false,
        addOrdit:false,
        id: "",
        name: "",
        price: "",
        formData: {},
        record: {}
    };
    if (props.isAddProduct){
        this.state.showCreateForm = props.isAddProduct;
    }
    else if (props.singleProduct) {
        this.state.id = props.singleProduct.product.productId;
        this.state.name = props.singleProduct.product.name;
        this.state.price = props.singleProduct.product.price;
        this.state.record = props.singleProduct.product;
        this.state.showCreateForm = props.singleProduct.isEditProduct;
        this.state.addOrdit = props.singleProduct.isEditProduct;
        console.log(this.state.name)

    }else if(props.closeForm){
        this.state.showCreateForm = props.closeForm;
    }

}

handleSubmit = event => {
    event.preventDefault();

    if(this.state.addOrdit){

        this.setState({
            record: {
                productId: this.state.id,
                name: this.state.name, 
                price: this.state.price
            }
        });
    this.props.onAddFormSubmit(this.state.record);

    }else{
        console.log("In submit befor set "+this.state.name)
        this.setState({
            formData: {
                name: this.state.name, 
                price: this.state.price
            }
        });
        console.log("In submit after set"+this.state.formData)
        this.props.onAddFormSubmit(this.state.formData);
    }
}

//On cancel button click close form
closeCreateForm = () => {
    this.setState({ showCreateForm: false })
    this.props.onFormControl();
}

//Open form
openCreateCustomer = () => {
    this.setState({ showCreateForm: true })
}

render() {

    let formTitle;
    let buttonName;
    if (this.state.addOrdit) {
        formTitle = "Edit Product";
        buttonName = "Edit";
    } else {
        formTitle = "New Product";
        buttonName = "Create";
    }

    return (
        <div>
            <Modal size='small' 
            closeOnTriggerMouseLeave={false} 
            open={this.state.showCreateForm}>
                <Modal.Header>
                    {formTitle}
                </Modal.Header>
                <Modal.Content>
                    <Form onSubmit={this.handleSubmit}>

                        <Form.Field>
                            <label>Name</label>
                            <input type="text" placeholder='Name' name="name"
                                value={this.state.name}
                                onChange={(e) => this.setState({name: e.target.value})} />
                        </Form.Field>

                        <Form.Field>
                            <label>Address</label>
                            <input  placeholder='Price' name="price"
                                value={this.state.price}
                                onChange={(e) => this.setState({price: e.target.value})} />
                        </Form.Field>

                        <br />
                        <Button type='submit' icon labelPosition='right'  
                            floated='right' color='green'>
                                <Icon name='check'/>
                                {buttonName}
                            </Button>
                        <Button floated='right' 
                        onClick={this.closeCreateForm} color='black'>
                            Cancel
                        </Button>
                        <br />
                    </Form>

                </Modal.Content>
            </Modal>

        </div>
    )
}

}
5
  • React state updates are asynchronous. Does this answer your question? React setState not updating state Commented Mar 16, 2020 at 3:08
  • @DrewReese Is It happening because of console? Commented Mar 16, 2020 at 5:48
  • Is what happening because of console? Commented Mar 16, 2020 at 6:00
  • I have used console to check is the state has value or not and then I setState. The answer you suggested has console too. Commented Mar 16, 2020 at 6:12
  • That is a coincidence, it's just a common thing that devs sometimes also try to log state immediately after setting it. In your code you set state then immediately call onAddFormSubmit(this.state.formData); (or this.state.record), but at this point the state (this.state.formData or this.state.record) hasn't been updated yet. Commented Mar 16, 2020 at 6:16

1 Answer 1

1

React state is asynchronous, so accessing state just after a setState call will still be accessing the current value of state and not the expected next state.

A small refactor allows you to set state and submit the same value/object. Construct the object you will be saving to state first, then update state and submit it.

setState can also take an optional second parameter which is a callback function guaranteed to be called after state has been updated, so you can console log state updates there instead in order to log the next state.

handleSubmit = event => {
  event.preventDefault();

  if (this.state.addOrdit) {
    const newRecord = {
      productId: this.state.id,
      name: this.state.name, 
      price: this.state.price
    };

    this.setState({ record: newRecord });
    // submit same new record saved to state
    this.props.onAddFormSubmit(newRecord);
  } else {
    const formData = {
      name: this.state.name, 
      price: this.state.price
    };

    console.log("In submit before set " + this.state.name);
    this.setState({ formData }, () => {
      // now see updated state!!
      console.log('setState callback', this.state.formData);
    });

    // still old data
    console.log("In submit after set" + this.state.formData);
    // submit same new form data saved to state
    this.props.onAddFormSubmit(formData); 
  }
}
Sign up to request clarification or add additional context in comments.

2 Comments

If you could help me with this question? I want to add pagination in that I want to show 5 record on page and no of pages in drop-down on left side and current page on right side also change the page values on drop-down selection

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.