I have a problem with updating the state of parent component with a props from child component. It seems the following code is not working, however it looks fine
setUsersList(prevState => {
return [...prevState, data];
});
My parent component receives an object. Console.log(data) outputs the object received from child component. However, when console logging updated state (console.log(usersList)) it returns an empty array
Parent component:
import React, { useState } from "react";
import AddUser from "./components/Users/AddUser";
import UsersList from "./components/Users/UsersList";
function App() {
const [usersList, setUsersList] = useState([]);
const addUserHandler = data => {
console.log(data);
setUsersList(prevState => {
return [...prevState, data];
});
console.log(usersList);
};
return (
<div>
<AddUser onAddUser={addUserHandler}></AddUser>
<UsersList users={usersList}></UsersList>
</div>
);
}
export default App;
Child component:
import React, { useState } from "react";
import Button from "../UI/Button";
import Card from "../UI/Card";
import styles from "./AddUser.module.css";
const AddUser = props => {
const [inputData, setInputData] = useState({ name: "", age: "" });
const addUserHandler = event => {
event.preventDefault();
if (
inputData.age.trim().length === 0 ||
inputData.name.trim().length === 0
) {
return;
}
if ( inputData.age < 1) {
return;
}
props.onAddUser(inputData);
console.log(inputData.name, inputData.age);
setInputData({ name: "", age: "" });
};
const usernameChangeHandler = event => {
setInputData({ ...inputData, name: event.target.value });
};
const ageChangeHandler = event => {
setInputData({ ...inputData, age: event.target.value });
};
return (
<Card className={styles.input}>
<form onSubmit={addUserHandler}>
<label htmlFor="username">Username</label>
<input
id="username"
type="text"
onChange={usernameChangeHandler}
value={inputData.name}
></input>
<label htmlFor="age">Age (Years)</label>
<input
id="age"
type="number"
onChange={ageChangeHandler}
value={inputData.age}
></input>
<Button type="submit">Add User</Button>
</form>
</Card>
);
};
export default AddUser;
CodePudding user response:
Due to the way react re-renders components, your console may not log with the expected state change. Instead you can use useEffect for debugging purposes:
parent component
useEffect(() => {
console.log("usersList", usersList);
}, [usersList])
alternatively, having a console.log statement in the body of your functional component should log the correct 'usersList'.
const [usersList, setUsersList] = useState([]);
console.log("usersList", usersList);
CodePudding user response:
The state variable won't change right away when you call setState
function from the useState
hook. Since it is an asynchronous event.
So you might need to write your code like this to see the right console.log
const addUserHandler = data => {
console.log(data);
setUsersList(prevState => {
const temp = [...prevState, data];
console.log(temp); // like this
return temp;
});
};
If the state is not updating in the UI. Please paste the error or the warning message.
CodePudding user response:
Since setUserList is async function, you can not see the changes on console in the addUserHandler function.
function App() {
const [usersList, setUsersList] = useState([]);
const addUserHandler = data => {
console.log(data);
setUsersList(prevState => {
return [...prevState, data];
});
};
console.log(usersList);
return (
<div>
<AddUser onAddUser={addUserHandler}></AddUser>
<UsersList users={usersList}></UsersList>
</div>
);
}
export default App;
This will work. Thanks.