I have a case here, which is to make a remember me function when logging in.
So, yesterday I got an online repo on codesandbox which contains reactjs component remember me.
Then I want to convert it into react hooks.
The code is like this (React Component original)
import React from "react";
class RememberMe extends React.Component {
static displayName = "RememberMe";
state = {
email: "",
password: "",
isChecked: false
};
componentDidMount() {
if (localStorage.checkbox && localStorage.email !== "") {
this.setState({
isChecked: true,
email: localStorage.username,
password: localStorage.password
});
}
}
onChangeValue = (event) => {
this.setState({
[event.target.name]: event.target.value
});
};
onChangeCheckbox = (event) => {
this.setState({
isChecked: event.target.checked
});
};
loginSubmit = () => {
const { email, password, isChecked } = this.state;
if (isChecked && email !== "") {
localStorage.username = email;
localStorage.password = password;
localStorage.checkbox = isChecked;
}
};
render() {
const { email, password, isChecked } = this.state;
return (
<div>
<form>
<table align="center">
<tr>
<td>
<label>Email</label>
</td>
<td>
<input
type="email"
name="email"
value={email}
onChange={this.onChangeValue}
/>
</td>
</tr>
<tr>
<td>
<label>Password</label>
</td>
<td>
<input
type="password"
name="password"
value={password}
onChange={this.onChangeValue}
/>
</td>
</tr>
<tr>
<td colSpan="2">
<input
type="checkbox"
checked={isChecked}
name="lsRememberMe"
onChange={this.onChangeCheckbox}
/>
<label>Remember me</label>
</td>
</tr>
<tr>
<td colSpan="2">
<input type="button" value="Login" onClick={this.loginSubmit} />
</td>
</tr>
</table>
</form>
</div>
);
}
}
export default RememberMe;
However, when it was finished, I tried to convert it into hooks, but it didn’t work properly, I thought, "Is there something wrong in my code? Thank you
import React, { useState, useEffect } from "react";
const Me = () => {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [isChecked, setIsChecked] = useState(false);
useEffect(() => {
if (localStorage.checkbox && localStorage.email !== "") {
setEmail({ email: localStorage.username });
setPassword({ password: localStorage.password });
setIsChecked({
isChecked: true
});
}
}, []);
const onChangeValue = (event) => {
setIsChecked({
[event.target.name]: event.target.value
});
};
const onChangeCheckbox = (event) => {
setIsChecked({
isChecked: event.target.checked
});
};
const loginSubmit = () => {
if (isChecked && email !== "") {
localStorage.username = email;
localStorage.password = password;
localStorage.checkbox = isChecked;
}
};
return (
<div>
<form>
<table align="center">
<tr>
<td>
<label>Email</label>
</td>
<td>
<input
type="email"
name="email"
value={email}
onChange={onChangeValue}
/>
</td>
</tr>
<tr>
<td>
<label>Password</label>
</td>
<td>
<input
type="password"
name="password"
value={password}
onChange={onChangeValue}
/>
</td>
</tr>
<tr>
<td colSpan="2">
<input
type="checkbox"
checked={isChecked}
name="lsRememberMe"
onChange={onChangeCheckbox}
/>
<label>Remember me</label>
</td>
</tr>
<tr>
<td colSpan="2">
<input type="button" value="Login" onClick={loginSubmit} />
</td>
</tr>
</table>
</form>
</div>
);
};
export default Me;
https://codesandbox.io/s/remember-me-localstorage-forked-crpt1z
>Solution :
Look closely at the types of your state.
Unlike with a class component where there’s one state
object with various keys, each state atom is now separate and should just hold the value itself, yet you’re setting objects into them, e.g.
setEmail({ email: localStorage.username });
Invocations like that should be just
setEmail(localStorage.username);
and so on.
You also don’t need useEffect()
; just use useState
‘s function initialization:
import React, { useState } from "react";
function Me() {
// State, initial state loaded from local storage if set
const [email, setEmail] = useState(() => (localStorage.checkbox ? localStorage.username : ""));
const [password, setPassword] = useState(() => (localStorage.checkbox ? localStorage.password : ""));
const [isChecked, setIsChecked] = useState(() => !!localStorage.checkbox);
const loginSubmit = () => {
if (isChecked && email !== "") {
localStorage.username = email;
localStorage.password = password;
localStorage.checkbox = isChecked ? "1" : "";
alert("Okay!");
}
};
return (
<div>
<form>
<table align="center">
<tr>
<td>
<label>Email</label>
</td>
<td>
<input type="email" name="email" value={email} onChange={(e) => setEmail(e.target.value)} />
</td>
</tr>
<tr>
<td>
<label>Password</label>
</td>
<td>
<input type="password" name="password" value={password} onChange={(e) => setPassword(e.target.value)} />
</td>
</tr>
<tr>
<td colSpan="2">
<input
type="checkbox"
checked={isChecked}
name="lsRememberMe"
onChange={(e) => setIsChecked(e.target.checked)}
/>
<label>Remember me</label>
</td>
</tr>
<tr>
<td colSpan="2">
<input type="button" value="Login" onClick={loginSubmit} />
</td>
</tr>
</table>
</form>
</div>
);
}