Form with list in React

Asked

Viewed 142 times

3

I’m on my first project with React, and I’m totally lost with a.
My form must submit customer data, and within that same form I can have two addresses. Since both addresses have the same attributes, I decided to create an address component which I called CustomerAddress.
Follows the code:

export default class Create extends Component {
  constructor() {
    super();

    this.state = {
    documentType: 1,
    name: '',
    fullName: '',
    documentNumber: '',
    telephoneNumber: '',
    mobilePhoneNumber: '',
    email: '',
    dueDate: 1,
  };

  //Código ignorado
}

render() {
return (
  <div>
    <h1>Novo Cliente</h1>

    <hr />

    <form className="form-group">
      <div className="row">
        <BsInput col="col-lg-3 col-md-3 col-sm-6" htmlFor="customerName" label="Nome Fantasia" id="customerName" name="customerName" value={this.name} onChange={this.saveChanges.bind(this, 'name')} />

        <BsInput col="col-lg-3 col-md-3 col-sm-6" htmlFor="customerFllName" label="Razão Social" id="customerFllName" name="customerFullName" value={this.fullName} onChange={this.saveChanges.bind(this, 'fullName')}/>

        <BsSelect col="col-lg-2 col-md-2 col-sm-6" htmlFor="documentType" label="Documento" id="documentType" name="documentType" listItems={this.state.documentTypes} onChange={this.setDocumentType} value={this.documentType} />

      </div>

      <div className="row row-top-30">
        <BsInputMask mask="(99) 9999-9999" maskChar=" " col="col-lg-3 col-md-3 col-sm-6" htmlFor="comercialPhone" label="Tel. Comercial" id="comercialPhone" name="comercialPhone" value={this.telephoneNumber} onChange={this.saveChanges.bind(this, 'telephoneNumber')}/>

        <BsInputMask mask="(99) 99999-9999" maskChar=" " col="col-lg-3 col-md-3 col-sm-6" htmlFor="mobilePhone" label="Tel. Celular" id="mobilePhone" name="mobilePhone" value={this.mobilePhoneNumber} onChange={this.saveChanges.bind(this, 'mobilePhoneNumber')}/>

        <BsInput col="col-lg-3 col-md-3 col-sm-6" type="email" htmlFor="email" label="E-mail" id="email" name="email" value={this.email} onChange={this.saveChanges.bind(this, 'email')}/>

        <BsInput col="col-lg-2 col-md-2 col-sm-6" type="number" min="1" max="31" htmlFor="dueDate" label="Vencimento da Fatura" id="dueDate" name="dueDate" value={this.dueDate} onChange={this.saveChanges.bind(this, 'dueDate')}/>
      </div>

      <h3 className="row-top-30">Endereço</h3>

      <CustomerAddress />

      <h3 className="row-top-30">Endereço de Cobrança</h3>

      <CustomerAddress />
    </form>
  </div>
);
}


My component CustomerAddressis like this:

export default class CustomerAddress extends Component {
  constructor() {
    super();
    this.state = {
       zipCode: '',
       address: '',
       number: '',
       complement: '',
       location: '',
       city: '',
       state: '',
       country: ''
    };
  }
//Código ignorado

render() {
return (
  <div>
    <div className="row row-top-30">
      <div className="form-group" className="col-lg-2 col-md-2 col-sm-6">
        <label htmlFor="zipCode">CEP</label>
        <InputMask mask="99999-999" className="form-control" id="zipCode" onKeyPress={this.buscaCep} onChange={this.setChange.bind(this, 'zipCode')} name="zipCode" />
        <span className="error">{this.state.msgErro}</span>
      </div>

      <BsInput col="col-lg-4 col-md-4 col-sm-6" htmlFor="address" value={this.state.address} label="Logradouro" id="address" name="address" onChange={this.setChange.bind(this, 'address')} />

      <BsInput col="col-lg-2 col-md-2 col-sm-6" htmlFor="number" label="Número" id="number" name="number" onChange={this.setChange.bind(this, 'number')} value={this.state.number} />

      <BsInput col="col-lg-3 col-md-3 col-sm-6" htmlFor="complement" label="Complemento" id="complement" name="complement" value={this.state.complement} onChange={this.setChange.bind(this, 'complement')}/>
    </div>

    <div className="row row-top-30">
      <BsInput col="col-lg-4 col-md-4 col-sm-6" htmlFor="location" label="Bairro" id="location" name="location" value={this.state.location} onChange={this.setChange.bind(this, 'location')}/>

      <BsAutoComplete col="col-lg-4 col-md-4 col-sm-6" htmlFor="city" label="Cidade" id="city" name="city" value={this.state.city} placeholder="Selecione uma cidade" items={this.state.cities} onChange={this.setChange.bind(this, 'city')}/>
      <BsAutoComplete col="col-lg-3 col-md-3 col-sm-6" htmlFor="state" label="Estado" id="state" name="state" value={this.state.state} placeholder="Selecione um estado" items={this.state.states} onChange={this.setChange.bind(this, 'state')}/>
    </div>
  </div>
);
}
}

My question is: I know that in a Submit method I can access customer data using the client’s own state, so that if I wanted to access the name I can simply do this.state.name, but how do I get the inputs that are inside the component CustomerAddress?

  • You want to access the component status data CustomerAddress in his father component, that’s it?

  • That’s right @Caiofelipepereira

  • 1

    I gave an answer that speaks exactly about it. See if she helps you... otherwise I give more details here.

  • @Caiofelipepereira It helped a lot, in fact its response joins other research I did that pointed out a solution. Thank you.

1 answer

2


Just to formalize the answer and help other people who might come here: There is a simple solution, among some others, to get the value of a child component within a parent component, which is to provide a method via props of the parent component to the child, causing it to change a state of the parent component. See

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

    this.state = {
      value: 0
    }

    this.getChildValue = this.getChildValue.bind(this);
  }

  getChildValue(value) {
    this.setState({
      value
    });
  }

  render() {
    return (
      <div>
        <ComponenteFilho parentCallback={this.getChildValue} />
        <p>{this.state.value}</p>
      </div>
    )
  }
}

The parent component renders <ComponenteFilho /> providing inparentCallback (which may be the name you choose) a method that is linked with the state of this parent component itself. In the child, you just run it like any other.

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

    this.state = {
      valueToParent:10
    }
  }

  render () {
    return(
      <button onClick={this.props.parentCallback(this.state.valueToParent)}>Try me!</button>
    )
  }
}

Once the value of the state of the child component is changed, when clicking the button and executing the method, the value of the state in the parent component will also be changed and rendered according to the rule which, in this case, is simply print the value in a tag <p>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.