1

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 :)

1 Answer 1

1

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

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

2 Comments

Hey Nikita, big thanks, it is working now,, but state in SimpleForm must be left alone ;) So actually, your points 1 and 3 are valid, but not 2 . Removing the state from SimpleForm will cause an "date is not defined" error. It must be left alone in order to update Object in array after submitting. Nevertheless, your solution is the right one. Thank you.
@PH Hmm, you are right. It can work if we get rid of submit button and will autosubmit on selection changed. You can look at my sandbox codesandbox.io/s/affectionate-antonelli-j6tqb?file=/src/…

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.