skip to Main Content

I have a page that passes a client item to a component, this component then passes the client item to its child component. This child component edits the client item. How can I make the child’s edits go directly to the parent item? Currently, after the edits in NewContactModal.jsx, the parent component is not affected and shows the data it had previously pulled.

Here is my code:

// Sale_resume.jsx
const { sale, selectedItems, setTotals, setCustomer } = useContext(SaleContext)

<ContactInfoModal
  client={sale.customer}
  show={showContactInfoModal}
  handleClose={handleCloseContactInfoModal}
/>

// ContactInfoModal.jsx
const ContactInfoModal = ({ client, show, handleClose, refreshContactList  }) => {
  // ...
  <p className='m-0 fw-bold'>Nome</p>
  <p>{client.short_name}</p>
  <p className='m-0 fw-bold'>CPF/CNPJ</p>
  <p>{client.federal_tax_id}</p>
  <NewContactModal
    contact={client}
    show={updateContactModalShow}
    handleClose={handleCloseUpdateContactModal}
  />
  // ...
}

// NewContactModal.jsx
const NewContactModal = ({ show, handleClose, contact, getContacts }) => {
  const handleSubmit = async () => {
    // ...
    let response = {}
    if (contact) {
      response = await gestupApi.putContact(contact.id, { name, federalTaxId, address, neighborhood, number, zip, complement, selectedState, selectedCity, phoneNumber, email, suframa, stateTax, cityTax, contributorType, channel, birthDate })
    } else {
      response = await gestupApi.postContact({ name, federalTaxId, address, neighborhood, number, zip, complement, selectedState, selectedCity, phoneNumber, email, suframa, stateTax, cityTax, contributorType, channel, birthDate })
    }
    if (response.code == 200) {
      resetStates()
      getContacts ? getContacts() : ""
      contact ? toast.success("Contato atualizado com sucesso") : toast.success("Contato criado com sucesso")
    } else {
      contact ? toast.error("Falha ao atualizar o contato") : toast.error("Falha ao criar o contato")
    }
    handleClose()
  }
  // ...
  <div className="form-group">
    <label className="control-label" id="full_name_label">{contributorType == "COMPANY" ? "Razão Social*" : "Nome*"}</label>
    <input type="text" className='form-control' maxLength={60} onChange={(e) => setName(e.target.value)} value={name} />
  </div>
  <button className='btn btn-gestup' disabled={isDisabled} onClick={() => { handleSubmit() }}>Confirmar</button>
  // ...
}

2

Answers


  1. You are getting the original sale.customer/client/contact value from the Context API. That Context API seems to also make available some of the set-state-functions for its data. And it is that data you are changing in the descendent component.

    So you could have the NewContactModal update the data on the backend, and then update the state variable in the SaleContext by also using the Context API in NewContactModal.jsx.

    An alternative would be to pass down a function from the parent that the child can call when the contact information has been modified, enabling the parent to do some action (such as re-fetching the data….but the NewContactModal already has the updated data, right?)

    Note: the fact that this data changes variable/prop names multiple times is … likely a bad practice. When it comes to coding, Consistency Is King. Name something and try to use that name consistently. Otherwise things get really confusing for yourself, for your team mates, and worst of all….for Future You ("what the heck was I doing???")

    Login or Signup to reply.
  2. Or you could pass a callback as prop to child and have it call the callback whenever the data updates

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search