1

I have an array of objects, I did a map on that array now I want to change specific object values. I used onChange method inside map() function. It not working properly could someone please help me to achieve this problem solution.

thanks

localPreRoutingCall &&
    localPreRoutingCall.map((item, index) => (
      <>
        <div className="pre-route-title">{item && item.field_title}</div>
        <textarea
          placeholder="Enter something"
          className="pre-route-textarea"
          value={item && item.value}
          onChange={(e) => {
            e.persist();
            changeObjectValue(e.target.value, item);
          }}
        />
        <div className="pre-route-description">
          {item && item.description}
        </div>
      </>
    ))

A function where I am updating object value

 const changeObjectValue = (value, item) => {
    console.log("@@ array", value);
    let localArray = localPreRoutingCall;
    var index = _.findIndex(localArray, { id: item.id });
    localArray.splice(index, 1, { ...item, value: value });
    setLocalPreRoutingCall(localArray);
  };
4
  • Can you try to provide key property to map the content container? Commented Oct 15, 2021 at 19:05
  • I tried but I am sorry I was not able to achieve my goal. when I type something in textarea it just updates a single character as I type Jonas it just updated S not like full name Commented Oct 15, 2021 at 19:06
  • 1
    so you should also try to do {...item, value: oldValue + value} Commented Oct 15, 2021 at 19:08
  • actually, when I type name as Jonas it re-render component 5 time and it just return single character on each render Commented Oct 15, 2021 at 19:09

3 Answers 3

3

Like said in the comments, you have to pass a key prop to what you're rendering so React knows what changes.

I don't see a reason for you to use the e.persist function when you're passing the value immediately.

import { Fragment } from "react";

localPreRoutingCall?.map((item, i) => (
  <Fragment key={item.id}>
    <div className="pre-route-title">{item.field_title}</div>
    <textarea
      placeholder="Enter something"
      className="pre-route-textarea"
      value={item.value}
      onChange={(e) => changeObjectValue(e.target.value, i)}
    />
    <div className="pre-route-description">
      {item.description}
    </div>
  </Fragment>
))

You also didn't clone the localPreRoutingCall state array before changing its value.

Another reason why React won't know what changed.

const changeObjectValue = (value, i) => {
  const localArray = [...localPreRoutingCall];
  localArray[i].value = value;
  setLocalPreRoutingCall(localArray);
};
Sign up to request clarification or add additional context in comments.

Comments

1

One obvious problem I can see is that you aren't giving the mapped components keys.

<> can't be used in map because it can't be passed a key, so this would be an improvement

<React.Fragment key={item.id}>

1 Comment

I tried but I am sorry I was not able to achieve my goal. when I type something in textarea it just updates a single character as I type Jonas it just updated S, not like full name
1

Instead of using

localArray.splice(index, 1, { ...item, value: value });

Use

localArray[index].value = value

3 Comments

Actually, It just updates the last character of the entered text. I want to store full text
Find what you are getting from "e.target.value ". If it only last character then you need to concat it with the previous value
I need some help in code, could you please share some code how can I achieve it

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.