5

I am trying to use state to hide Semantic-UI Model form also to pass JSON to Customer class to add new customer. I am able to pass the value but in the end there is only one value.

View to add new customer

When I start typing name, in console panel on 1st character name is empty "" and on 2nd character there is single "a" name

In address same thing happening with address

on create button click on button click name is empty

when i click create button the name is empty"" and address has value.

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

export default class AddCustomer extends React.Component {

constructor(props) {
    super(props);
    this.state = {
        showCreateForm:false,
        formData:{
            name: '',
            address: ''
        }
    }
    this.handleChangeName = this.handleChangeName.bind(this);
    this.handleChangeAddress = this.handleChangeAddress.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
}

handleChangeName(event) {
    const value = event.target.value;

    console.log(value);

    this.setState({formData:{name:value}});

    //when i go to add input the formData is still empty name is empty.
    //name: ""
    //address: ""
    console.log(this.state.formData);
}

handleChangeAddress(event) {
    const value = event.target.value;
    console.log(value);
    this.setState({formData:{address:value}});

    //name: "ram" but now there is no address in formData
    console.log(this.state.formData);
}

handleSubmit(event) {
    event.preventDefault();

    ////address: "aaaaa" now there no name in formData
    console.log(this.state.formData);

    this.setState({formData:{
        name:this.state.name, address:this.state.address
    }});
    this.props.onAddFormSubmit(this.state.formData);
}

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

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

render() {

    return (
        <div>
            <Modal closeOnTriggerMouseLeave={false} trigger={
                <Button color='blue' onClick={this.openCreateCustomer}>
                    New Customer
        </Button>
            } open={this.state.showCreateForm}>
                <Modal.Header>
                    Create customer
    </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 = {this.handleChangeName}/>
                        </Form.Field>

                        <Form.Field>
                            <label>Address</label>
                            <input type="text" placeholder ='Address' name = "address"
                                value = {this.state.address}
                                onChange = {this.handleChangeAddress}/>
                        </Form.Field>
                        <br/>
                        <Button type='submit' floated='right' color='green'>Create</Button>
                        <Button floated='right' onClick={this.closeCreateForm} color='black'>Cancel</Button>
                        <br/>
                    </Form>

                </Modal.Content>
            </Modal>

        </div>
    )
}

}
Rahul Waghmare
  • 125
  • 1
  • 2
  • 9

4 Answers4

6

With these lines you are replacing your whole state with the value of one field:

Your initial state:

 state = {
       formData: {
          name: "",
          address: ""
       }
    }

Your state after this line:

this.setState({formData:{address:value}});

 state = {
       formData: {
          address: ""
       }
    }

And with this line: this.setState({formData:{name:value}});

state = {
       formData: {
          name: ""
       }
    }

As mentioned in the answer by Greg b, you have to change the value of the specific key and copy rest as they are. You can also use spread operator to copy rest of the unmodified fields easily.

this.setState({...this.state.formData, address: value})

will only change the address and copy rest of the state as it is. This comes handy when you have multiple fields in the state.

Bikram Karki
  • 985
  • 8
  • 8
4

This is your state

formData:{
  name: '',
  address: ''
}

Change both these lines respectively

this.setState({formData:{address:value}});

this.setState({formData:{name:value}});

To

this.setState({formData:{name: this.state.formData.name, address:value}});`

this.setState({formData:{name:value, address: this.state.formData.address}});`
Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
Greg M
  • 398
  • 1
  • 9
0
function handleChangeName(event) {
    const value = event.target.value;
    this.setState((prevState)=>({ formData: { name: value, address: prevState.formData.address }}),
    ()=>{ console.log(this.state.formData)});
}

function handleChangeAddress(event) {
    const value = event.target.value;
    this.setState((prevState)=>({ formData: { name: prevState.formData.name, address: value}}),
    ()=>{ console.log(this.state.formData)});
}
  1. if you what to something next after setState() or state update, you have to use call back function.
  2. State Updates are Merged
-2

It looks like you aren't accessing the state correctly in the render(), I see you doing this.state.name and this.state.address rather than this.state.formData.nameand this.state.formData.address.

Also you probably shouldn't be storing your form data in a single state object, break it out into a field for each input, e.g.

this.state = {
  showCreateForm: false,
  name: "...",
  address: "..."
}

You cannot update only part of an object in state, you need to update the whole thing. When you do this.setState({formData:{address:value}}); or are essentially setting this.state.formData.name to undefined, since the object is now going to only be { address: value }

Bill Metcalf
  • 650
  • 4
  • 6