javascriptarraysreactjsobjectsubmit-button

Passing an object Id by submit button in order to find and change value in array after submiting (react)


I want to update a value of an object nested in array after choosing new date from select button and then submiting it in order to change it.

The button (select) is nested with a rendered array object invoice in Accordion from material ui and is supposed to change a date (for now a year only) and save it while comparing its Id number.

I have two components : sideBar and simpleForm

const SideBar = ({ className }) => {
  const [invoices, setInvoice] = useState([
    { label: 'Test', invoiceDate: '2021', id: 0 },
    { label: 'Test', invoiceDate: '2022', id: 1 },
    { label: 'Test', invoiceDate: '', id: 2 },
  ])


  const addInvoiceDate = (date, invoice) => {
    setInvoice(
      invoices.map((x) => {
        if (x.id === invoice.id)
          return {
            ...x,
            invoiceDate: date,
          }
        return x
      })
    )
  }

  return (
    <>
      <Wrapper>
        <S.MainComponent>
          <div>
            {invoices.map((invoice) => {
              return (
                <Accordion>
                  <AccordionSummary expandIcon={<ExpandMoreIcon />}>
                    <div key={invoice.id}>
                      {invoice.label}
                      {invoice.invoiceDate}
                    </div>
                  </AccordionSummary>
                  <AccordionDetails>
                    <SimpleForm addInvoiceDate={addInvoiceDate} />
                  </AccordionDetails>
                </Accordion>
              )
            })}
          </div>
        </S.MainComponent>
      </Wrapper>
    </>
  )
}

Simple Form :

const SimpleForm = ({ addInvoiceDate }) => {
  const [date, setDate] = useState('')
  const handleSubmit = (e) => {
    e.preventDefault()
    addInvoiceDate(date)
  }

  function range(start, end) {
    return Array(end - start + 1)
      .fill()
      .map((_, placeholder) => start + placeholder)
  }

  const Years = range(2021, 4000)
  const Options = []
  Years.forEach(function (element) {
    Options.push({ label: element, value: element })
  })

  return (
    <form onSubmit={handleSubmit}>
      <select value={date} required onChange={(e) => setDate(e.target.value)}>
        {Options.map((option) => (
          <option value={option.value}>{option.label}</option>
        ))}
      </select>
      <input type='submit' value='Save' />
    </form>
  )
}

My problem is, i have no clue how can i succesfully pass an id number of array object to addInvoiceDate (change invoice date)in order to find it in orginal array, compare it and then submit new value. I was testing adding a new object with a new year value and it worked, but in that case i dont have to find an id of object. Its a little bit harder if i want actually find a previous one and update it through comparing id.

Any ideas how it should be done ? Probably i overlooked something or dont have enough expierience yet :)


Solution

  • How about this

    1. <SimpleForm addInvoiceDate={(date) => addInvoiceDate(date, invoice)} date={invoice.invoiceDate}/> in SideBar's return
    2. Remove the state from SimpleForm as we now have a date prop instead
    3. <select value={date} required onChange={(e) => addInvoiceDate(e.target.value)}> in SimpleForm's return

    Please leave a comment if there are questions