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>
    )
}

}
Rahul Waghmare
  • 125
  • 1
  • 2
  • 9
  • React state updates are asynchronous. Does this answer your question? [React setState not updating state](https://stackoverflow.com/questions/41446560/react-setstate-not-updating-state) – Drew Reese Mar 16 '20 at 03:08
  • @DrewReese Is It happening because of console? – Rahul Waghmare Mar 16 '20 at 05:48
  • Is *what* happening because of console? – Drew Reese Mar 16 '20 at 06: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. – Rahul Waghmare Mar 16 '20 at 06: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. – Drew Reese Mar 16 '20 at 06:16

1 Answers1

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); 
  }
}
Drew Reese
  • 165,259
  • 14
  • 153
  • 181
  • 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 – Rahul Waghmare Mar 16 '20 at 08:33
  • https://stackoverflow.com/questions/60692391/how-to-use-react-semantic-ui-dropdown-to-show-number-of-pages-and-selected-page – Rahul Waghmare Mar 16 '20 at 08:33