简体   繁体   中英

TypeError: Object.key is read-only

guys. I'm trying to implement Edit functionality on my invoice app, I pass invoice as props to form state like this:

const EditInvoice = ({invoice}) => {
  const [formInputs, setFormInputs] = useState([
  ]);
  const [form,setForm] = useState({
      clientCity : invoice.clientAddress.city,
      clientCountry : invoice.clientAddress.country,
      clientPostCode : invoice.clientAddress.postCode,
      clientStreet : invoice.clientAddress.street,
    clientEmail : invoice.clientEmail,
    clientName : invoice.clientName,
    createdAt : invoice.createdAt,
    description : invoice.description,
    id : invoice.id,
    items: formInputs,
    paymentDue : invoice.paymentDue,
    paymentTerms : invoice.paymentTerms,
      senderCity : invoice.senderAddress.city,
      senderCountry : invoice.senderAddress.country,
      senderPostCode : invoice.senderAddress.postCode,
      senderStreet : invoice.senderAddress.street,
    status : invoice.status,
    total : invoice.total
  })

At this point everything works, handleChange function works for everything except for formInputs, i tried setting formInputs state like this const [formInputs, setFormInputs] = useState([...invoice.items]); and using useEffect, like this:

useEffect(() =>{
    setFormInputs([...invoice.items])
  },[])

And they both populate the fields, but if I try updating my invoice items array I get read-only type error, just in case, here's what I used for my handleChange function

const handleItemChange = (index,e) =>{
    const values = [...formInputs]
    values[index][e.target.name] = e.target.value;
    values[index].total = (values[index].price * values[index].quantity).toFixed(2);
    setFormInputs(values)
  }

Hoping you guys could provide me with solution, Thanks in advance!

I don't know if it's a hacky way to do it, but this solution seems to work.

useEffect(() =>{
    invoice.items.map(item => setFormInputs(prevState => ([...prevState, {
      id : item.id,
      name : item.name,
      quantity : item.quantity,
      price : item.price,
      total : item.total
    }])))
    console.log(formInputs);
  },[])

The problem in your code is that your are trying to re-assign a const value that is read-only (it prevents the re-assignment). Define your values as let .

So instead of

const values

you should define it as

let values

Because state may be updated asynchronously, you should not rely on their values for calculating the next state.

change the method like this:

const handleItemChange = (index,e) =>{
  setFormInputs(prevValues => {
    const newValues = [ ...prevValues];
    newValues[index][e.target.name] = e.target.value;
    newValues[index].total = (values[index].price * values[index].quantity).toFixed(2);
    return newValues;
  })
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM