Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

148
Views
Changing the data in a child component without changing it in the parent

I am making changes to a set of data and the data is held in a parent components state I pass that data to a 2nd component but when I make changes to the data in the 2nd component it is changing the data in the first. Ive tried setting a variable to the value of the state in an effort to make a copy of it / also creating a new state in the 2nd component that is set from the initial data from the first. But For some reason I am still changing the initial data. Can anyone explain whats going on here?

Parent Component:

const [data, setData] = useState([]);
const [editing, setEditing] = useState(null);

{!!editing && (
        <EditInsurance state={editing} data={data} setEditing={setEditing} />
)}

2nd Component:

const [update, setUpdate] = useState([]);
const [List, setList] = useState([]);

//sets the data onLoad
 useEffect(() => {
    setList(data);
  }, []);

//edits the data
const handleClick = (item) => {
    let list = List;
    
    list.forEach((el) => {
      if (el.payerName === item.payerName) {
        el.state.push(state.value);
        if (!el.isActive) {
          el.isActive = true;
        }
      }
    });

    //update is an array containing only edited objects.
    setUpdate([...update, item]);
  };

When handleClick is fired and I console the data value in the parent component it has been updated. And I dont want to change that data until the user clicks save. How can I have a copy of the data exclusive to the 2nd component that doesn't manipulate the data in the Parent?

about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

Issue

The issue here is that the code is mutating the state objects.

const [update, setUpdate] = useState([]);
const [List, setList] = useState([]);

// sets the data onLoad
useEffect(() => {
  setList(data); // <-- (1) parent state passed as prop
}, []);

// edits the data
const handleClick = (item) => {
  let list = List; // <--(2) reference to state in parent

  list.forEach((el) => {
    if (el.payerName === item.payerName) {
      el.state.push(state.value); // <-- (3) mutation of parent state!
      if (!el.isActive) {
        el.isActive = true; // <-- (3) mutation of parent state!
      }
    }
  });

  // update is an array containing only edited objects.
  setUpdate([...update, item]);
};

Solution

Use/apply the immutable update patten. Any state that is being updated should be shallow copied into to new array/object reference. The spread syntax is a shallow copy by reference, this is why creating new array/object references is necessary to keep from mutating the original.

I'll assume that this child component just wants/needs to maintain its own copy of the data prop.

const [list, setList] = useState(data); // <-- (1) parent state passed as prop

// edits the data
const handleClick = (item) => {
  setList(list => list.map(el => { // <-- (2) array.map shallow copy
    if (el.payerName === item.payerName) {
      return {
        ...el, // <-- (3) shallow copy array element
        state: [...el.state, state.value], // <-- (4) shallow copy array
        isActive: !el.isActive, // <-- new property
      };
    }
    return el; // <-- not updating, just return current element
  }));
};
about 4 years ago · Juan Pablo Isaza Report

0

You can try to copy the list using a spread operator. On the child component, you can do something like:

function EditInsurance(props) {
  const [parentData, setParentData] = useState([...props.data]);
  ...
}

And then use the parentData on your child component, you don't even need the useEffect.

about 4 years ago · Juan Pablo Isaza Report

0

I'm not very sure but you can try something like -

const [List, setList] = useState([]);
const [newList, setNewList] = useState([]);

and along with -

 useEffect(() => {
    setList(data);
  }, []);

use -

 useEffect(() => {
    setNewList([...List])
  }, [List]);

This will make a cloned copy of the List props that you received, and now if you change this (push or setState), your parent component will not reflect the changes.

Now in your handleClick function, -

    const handleClick = (item) => {
        let MyList = [...newList]

        # this is brcause you are using map. So first push the data in MyList and then setState your newList, so that child component can re-render 
        
        MyList.forEach((el) => {
          if (el.payerName === item.payerName) {
            el.state.push(state.value);
            if (!el.isActive) {
              el.isActive = true;
            }
          }
        });

     # also include this
     setNewList(MyList) 

    setUpdate([...update, item]);

}

and use newList everywhere in your child component render method.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!