skip to Main Content

I have a state formData in which mappedColumn is one of the object as below

const [formData, setFormData]=useState({
               mappedColumns:[
               {
                 source:"MAIN SOURCE",
                 target:"MAIN TARGET",
                 transformationValue:"MAIN VALUE"
               }
              ]
            })

var targetIndex = 0;
let mappingConfig = [...formData.mappedColumns];
var mIndex = mappingConfig.findIndex(function(p){ return p.target== targetIndex})
mappingConfig[mIndex].source = 'source';
mappingConfig[mIndex].transformationValue = 'value';

When I made any changes to the variable mappingConfig the actual state variable formData.mappedColumns is getting updated with whatever values are assigned to mappingConfig. Why is it happening so. What is the soluion for this. Anyone please help !!

3

Answers


  1. The behavior you’re describing is likely due to the fact that objects in JavaScript are assigned by reference, not by value. When you perform let mappingConfig = […formData.mappedColumns];, you are creating a shallow copy of the array, but the objects within the array are still references to the same objects in memory. Therefore, when you modify properties of objects in mappingConfig, you’re actually modifying the same objects in formData.mappedColumns.

    To avoid this issue, you should create a deep copy of the objects within the array to ensure that changes to one object do not affect the other. One way to achieve a deep copy is to use the spread operator for both the array and the objects within it.

    Here’s an example of how you can create a deep copy in your case:

     const [formData, setFormData] = useState({
      mappedColumns: []
    });
    
    var targetIndex = 0;
    let mappingConfig = formData.mappedColumns.map(obj => ({ ...obj })); // Deep copy
    
    var mIndex = mappingConfig.findIndex(function (p) {
      return p.target === targetIndex;
    });
    
    mappingConfig[mIndex].source = 'source';
    mappingConfig[mIndex].transformationValue = 'value';
    
    // Now update the state with the new array
    setFormData({
      ...formData,
      mappedColumns: mappingConfig
    });
    

    In this example, map(obj => ({ …obj })) is used to create a new array with deep-copied objects. This way, changes to mappingConfig won’t affect the original formData.mappedColumns. Finally, when updating the state using setFormData, you create a new object with the updated mappedColumns array to ensure that the state update triggers a re-render.

    Login or Signup to reply.
  2. Instead of

    let mappingConfig = [...formData.mappedColumns];
    

    use

    let mappingConfig = formData.mappedColumns.map((value) => ({ ...value }));
    

    This is because you need to destructure the exact object that is being updated. Otherwise it will still point to old reference

    Login or Signup to reply.
  3. You should use deep clone to copy a data typeof Object

    //  let mappingConfig = [...formData.mappedColumns];
    let mappingConfig = JSON.parse(JSON.stringify(formData.mappedColumns))
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search