Having the following code structe, App is the parent, Inputs and List are children, for the moment we focus only on first two.
App.js:
import React from 'react';
import './App.css';
import Inputs from './components/Inputs';
import List from './components/List';
import { useState } from 'react';
function App() {
const [person, setPerson] = useState({ name: '', email: '' });
const people = [];
const callback = (e) => {
people.push(e);
};
console.log('people: ', people);
return (
<div>
<Inputs callback={callback} person={person} setPerson={setPerson} />
<List />
</div>
);
}
export default App;
Inputs.js:
const Inputs = ({ person, setPerson, callback }) => {
const updateName = (e) => {
setPerson({ ...person, name: e.target.value });
};
const updateEmail = (e) => {
setPerson({ ...person, email: e.target.value });
};
console.log('person: ', person);
return (
<div>
<label>name:</label>
<input onChange={updateName}></input>
<label>email:</label>
<input onChange={updateEmail}></input>
<button onClick={callback(people)}>add person</button>
</div>
);
};
export default Inputs;
When I introduce value into the inputs, the person object is getting updated, the log is showing that, but when I click on the button, the callback doesn’t work, it doesn’t update the people list in parent component.
How can I fix that?
>Solution :
There’s many things wrong in your code. Firstly, you can’t store values as plain variables in the body of a functional component. Every time the component re-renders, that value is re-initialized. So first you have to put people into state:
const [people, setPeople] = useState([]);
Secondly, when updating it you can’t push into it, cos you can’t mutate state, so when adding a person to that array you have to use the state setting function:
const addPerson = (person) => {
setPeople(people => [...people, person]);
};
Thirdly, in your child the on click parameter should be a function, not a function call. Also you reference the variable people in the child but you don’t actually pass it in as a prop so the child has no idea what that variable refers to. But with the people now in state and you having an add person function, you can just pass that in as a prop and then in the child have onClick={addPerson}