Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

151
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda