2

I am trying to use two states in my Add Customer JS one is used to hide the form and the second is used for JSON.

I want to use form-State to hide a form on cancel button click and the initial-State for JSON.

I want to do something like this Is it possible to have two states in one react component

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

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

}
1
  • Try hooks concept. Commented Mar 5, 2020 at 4:44

2 Answers 2

2

You can directly give initial state on the constructor. e.g

this.state ={showCreateForm: false, formModel:{name:'abc', address:'xyz'}}

Yes, you can have multiple state variables technically.

Sign up to request clarification or add additional context in comments.

4 Comments

Yeah, this would be the way to do it. On a side note, I think he should extract some components from the return function. All those semantic UI components in one return make it difficult to read.
@K4R1 thank you, can you tell me how can I extract. I am new to react so It will be great help for me.
@RahulWaghmare For starters, I recommend reading the official React docs on their website: reactjs.org/docs/… and reactjs.org/docs/…
@RahulWaghmare also here is a Youtube video covering the extracting: youtube.com/watch?v=5H7GIZO-5Rk
0

As it was already mentioned, yes, you could do it in the constructor. However you could go even further and declare it as a class member. Like following:

export default class Customer extends React.Component {
  state = {
    showCreateForm: false,
    form: {
      name: "",
      address: "",
    }
  }

  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleSubmit(event) {
    event.preventDefault();
    this.props.onAddFormSubmit(this.state.form);
    this.setState({
      ...this.state,
      form: {
        name: "",
        address: "",
      }
    });
  }



  // ...

  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.form.name}
                  onChange={this.handleChange}
                />
              </Form.Field>
              <Form.Field>
                <label>Address</label>
                <input
                  type="text"
                  placeholder="Address"
                  name="address"
                  value={this.state.form.address}
                  onChange={this.handleChange}
                />
              </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>
    );
  }
}

6 Comments

Thank you , can you please tell me. What should I do here in form.
<Form.Field> <label>Name</label> <input type="text" placeholder ='Name' name = "name" value = {this.state.initialState.name} onChange = {this.handleChange}/> </Form.Field>
@RahulWaghmare Do you mean something like that ^^ ? I have made an edit.
yes. can you tell me how can I do same in handleChange(event)
When I open form and start tying I get error on handleChange error - "A component is changing a controlled input of type text to be uncontrolled"
|

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.