Reputation: 330
I have a problem and I wonder what happend. My code is working fine and I change state values with Hooks. While everything is Ok , in my console I am facing previous state value in first click the button. When I click the button second time, state values start to come correctly. Is it logical thing according to Hooks or is there anything which I missed ?
My example Login.tsx :
import React, { useState, useContext, useEffect } from 'react';
import { Input, Button, DropDownMenu, Checkbox } from 'oneframe-react';
import { useTranslation } from 'react-i18next';
export const LoginPart = (props: any) => {
interface IState {
pageLanguage: any;
email: string;
password: string;
rememberMeCheck: boolean;
}
const initialState: IState = {
email: '',
password: '',
pageLanguage: '',
rememberMeCheck: false,
};
const [leftPartState, setState] = useState<any>(initialState);
const { t, i18n } = useTranslation();
const handleChange = (e: any) => {
setState((prevState: any) => ({
...prevState,
[e.target.name]: e.target.value,
}));
};
const handleCheckBoxChange = (e: any) => {
setState( (prevState : any) => ({
...prevState,
[e.target.name]: e.target.checked,
}));
};
const handleSubmit: any = (e: Event) => {
// fallowing code changes values but console situations are like :
// {email: "", password: "", pageLanguage: "", rememberMeCheck: false} -> first click and print
// {email: "", password: "", pageLanguage: "eng", rememberMeCheck: true} -> second click and print
setState({...leftPartState, email: '', password: '',rememberMeCheck:true, pageLanguage : localStorage.getItem("userlanguage")})
e.preventDefault();
console.log(leftPartState)
}
const handleClick : any = (selectedlang: any) => {
leftPartState.pageLanguage = selectedlang.Name
setState({...leftPartState, pageLanguage :leftPartState.pageLanguage })
i18n.changeLanguage(selectedlang.Name)
localStorage.setItem("userlanguage", selectedlang.Name)
}
useEffect(() => {
},[leftPartState])
const renderLoginPart = () => {
return (
<div className="render-login-part-container">
<form onSubmit={() => handleSubmit(event)}>
<DropDownMenu
className="select-language"
fullWidth={false}
options={{
data: [
{
Name: 'tr',
Id: 1,
},
{
Name: 'eng',
Id: 2,
}
],
displayField: 'Name',
displayValue: 'Id',
selected: 1
}}
onClick={(event : Event) => handleClick(event)}
/>
<Input
id="basicInput"
name="email"
caption={t('email')}
type="text"
onChange={handleChange}
value={leftPartState.email}
rightAdornments={() => {
return <i className="fal fa-envelope mr-1"></i>;
}}
className="login-input"
/>
<Input
id="basicInput"
name="password"
caption={t('password')}
type="password"
onChange={handleChange}
value={leftPartState.password}
rightAdornments={() => {
return <i style={{ cursor: "pointer" }} className="far fa-eye-slash"></i>;
}}
className="login-input mt-2"
/>
<div className="container">
<div className="row rememberme-and-forgotpassword-container">
<div>
{/* Not: Checked özelliği ayarlanmalı */}
<Checkbox
id={'rememberMeCheck'}
name={'rememberMeCheck'}
label={t("rememberMe")}
checked={leftPartState.rememberMeCheck?true:false}
onChange={handleCheckBoxChange}
className="rememberme-checkbox"
/>
</div>
<div>
<p className="forgot-password-text">{t("forgotPassword")}</p>
</div>
</div>
</div>
<Button
type="submit"
text={t("login")}
variant={'text'}
className={'custom-style-text-button'}
fullWidth
/>
</form>
</div>
)
}
return (
<span>
{renderLoginPart()}
</span>
)
}
export default connect((store: any) => ({ oneframe: store }))(LoginPart) as any;
Upvotes: 1
Views: 2323
Reputation: 3690
Setting a state is asynchronous in nature. You will not get the updated state just after setting it. You can use useEffect
hook to get updated value of state everytime it changes -
const handleSubmit: any = (e: Event) => {
// fallowing code changes values but console situations are like :
// {email: "", password: "", pageLanguage: "", rememberMeCheck: false} -> first click and print
// {email: "", password: "", pageLanguage: "eng", rememberMeCheck: true} -> second click and print
setState({...leftPartState, email: '', password: '',rememberMeCheck:true, pageLanguage : localStorage.getItem("userlanguage")})
e.preventDefault();
console.log(leftPartState)
}
useEffect(() => {
console.log(leftPartState);
}, [leftParState]);
Upvotes: 3