I´m trying to update a state inside this:
const [username, setUsername] = useState("");
const [room, setRoom] = useState("");
const [connected, setConnected] = useState(false);
const navigate = useNavigate();
const handleClick = (e) => {
e.preventDefault();
setConnected(true);
console.log(connected);
navigate("/chatroom", {
state: { username, room, connected },
});
};
<button
type="submit"
className="btn"
onClick={(e) => {
handleClick(e);
}}
>
The problem is that the state is not updating when I click. I know is an async problem, but I´ve tried the other options asked in SO but I dont get it.
CodePudding user response:
You have 2 ways to fix
The first one is using useEffect
to listen to connected
, username
, and room
values changes
const [username, setUsername] = useState("");
const [room, setRoom] = useState("");
const [connected, setConnected] = useState(false);
useEffect(() => {
if(connected && room && username) {
console.log(connected);
navigate("/chatroom", {
state: { username, room, connected },
});
}
}, [connected, room, username])
const navigate = useNavigate();
const handleClick = (e) => {
e.preventDefault();
setConnected(true);
};
The 2nd way, you can use class-based component instead of function-base component and then call setState
with callback
. Here is an example
setState({
connected: true,
username: "updated username",
room: "updated room"
}, () => {
navigate("/chatroom", {
state: { username, room, connected },
});
});
You can check the document here
CodePudding user response:
As you said, it is an asynchronous issue, as when you update the state, it is not immediately updated.
So you should refactor your function, and use useEffect
, to be triggered on connected
update:
const handleClick = (e) => {
e.preventDefault();
setConnected(true); // Update state async
};
useEffect(() => { // Triggered on connected update
// You can add here a logic for handling your state
if(connected)
navigate("/chatroom", {
state: { username, room, connected },
});
},[connected])