应用影响会话的身份验证更改并反应父组件
Apply auth changes that affect to session and react parent component
我将尽我所能在这里解释我的问题,但这将具有挑战性,所以请耐心等待。
我有一个使用 firebase 身份验证在 react + firebase 中开发的网络应用程序,登录目前仅由邮件和密码提供程序处理。我正在使用 React 路由器和 firebase 9。
当有人登录或注销时,身份验证令牌会保留在会话存储中,并且我在 App 组件(我页面的第一层)中有一个条件显示日志 in/register link 如果用户未登录,我的帐户 link 如果用户已登录。问题是我需要重新加载页面才能看到更改,登录时你会被重定向到另一条路线,但作为一个 React 应用程序,它不会重新加载整个页面。
我的App.js
const auth = getAuth();
const App = () => {
const [user, setUser] = useState();
const [expanded, setExpanded] = React.useState(true);
const [activeKey, setActiveKey] = React.useState('1');
const handleLogout = () => {
signOut(auth).then(()=> {
setUser({});
sessionStorage.clear();
console.log("unset user");
}).catch((err) => {
console.error(err);
alert(err.message);
})
};
onAuthStateChanged(auth, (user) => {
if (user) {
setUser(user)
sessionStorage.setItem("user", JSON.stringify(user))
const uid = user.uid;
console.log("set user")
} else {
}
});
useEffect(() => {
const loggedInUser = sessionStorage.getItem("user");
if (loggedInUser != null) {
const foundUser = loggedInUser.toString();
setUser(foundUser);
console.log(user)
}
}, []);
return (
<div>
<li className="nav-item">
{
(sessionStorage.user ?
<div className="d-flex justify-content-around row">
<Link className="nav-link" to="/user/perfil">Mi cuenta</Link>
</div>
: <Link className="nav-link" to="/login">Iniciar sesión / Registrarse</Link>
)
}
</li>
</div>
)
}
导出默认应用;
我的login.js
const auth = getAuth();
console.log(auth.currentUser);
const loginWithEmailAndPassword = async (email, password) => {
setPersistence(auth, browserSessionPersistence)
.then(() => {
signInWithEmailAndPassword(auth, email, password)
}).catch((error) => {
const errorCode = error.code;
const errorMessage = error.message;
alert(error.message)
})
}
class Login extends Component {
constructor() {
super();
this.state = {
email: "",
password: "",
redirect: "",
};
}
handleChangeEmail = () => {
this.setState({ email: document.getElementById("email").value });
console.log(this.state);
}
handleChangePassword = () => {
this.setState({ password: document.getElementById("password").value })
}
handleRedirect = () => {
this.setState({ redirect: "/aplicacion" });
console.log(this.state);
}
handleClick = async () => {
try {
await loginWithEmailAndPassword(
this.state.email,
this.state.password
);
this.handleRedirect();
} catch (err) {
console.error(err);
alert(err.message);
}
};
render() {
if (this.state.redirect) {
return <Navigate to={this.state.redirect} />
}
return (
<div className="d-flex justify-content-center" >
<div className="col-6">
<Link to='/recuperacion' className="tiny-text">He olvidado mi contraseña</Link>
</div>
</div>
)
}
}
编辑:我目前正在为将位于 App.js 中的应用程序的另一部分开发重定向检测功能,目前它只是一个数组,用于检查最后两条路线是否是与重定向情况相同,这对我来说太过暴力了,但这就是我现在所拥有的。
好的,我最终通过使用状态和挂钩解决了重定向问题让我解释一下:
我创建了一个名为 redirectState 的新状态及其 setter 和一个导航状态:
const [redirectState, setRedirectState] = useState()
let navigate = useNavigate()
然后我只需要在身份验证状态更改时设置它,以便应用程序知道何时重定向以及何时不重定向:
onAuthStateChanged(auth, (user) => {
if (user) {
setUser(user)
sessionStorage.setItem("user", JSON.stringify(user))
const uid = user.uid;
console.log("set user");
console.log(uid)
setRedirectState("redirect")
} else {
sessionStorage.clear();
setRedirectState()
}});
最后我使用了反应路由器 useNavigate 钩子来直接控制重定向:
useEffect(() => {
const loggedInUser = sessionStorage.getItem("user");
console.log("checking user...")
if (loggedInUser != undefined) {
const foundUser = loggedInUser.toString();
setUser(foundUser);
console.log(user);
navigate("/aplicacion")
}else{
console.log("no user")
navigate("/")
}}, [redirectState]);
它可能看起来很粗糙,但功能目前有效,当调用导航功能时所有组件更新,这样应用程序每次都会显示正确的 link,有一些我放错地方的资源想修复,但这将在另一点进行,如果我找到改进其编码方式的方法,将保持此 post 更新。
但现在我认为它已经解决了! :-)
我将尽我所能在这里解释我的问题,但这将具有挑战性,所以请耐心等待。
我有一个使用 firebase 身份验证在 react + firebase 中开发的网络应用程序,登录目前仅由邮件和密码提供程序处理。我正在使用 React 路由器和 firebase 9。
当有人登录或注销时,身份验证令牌会保留在会话存储中,并且我在 App 组件(我页面的第一层)中有一个条件显示日志 in/register link 如果用户未登录,我的帐户 link 如果用户已登录。问题是我需要重新加载页面才能看到更改,登录时你会被重定向到另一条路线,但作为一个 React 应用程序,它不会重新加载整个页面。
我的App.js
const auth = getAuth();
const App = () => {
const [user, setUser] = useState();
const [expanded, setExpanded] = React.useState(true);
const [activeKey, setActiveKey] = React.useState('1');
const handleLogout = () => {
signOut(auth).then(()=> {
setUser({});
sessionStorage.clear();
console.log("unset user");
}).catch((err) => {
console.error(err);
alert(err.message);
})
};
onAuthStateChanged(auth, (user) => {
if (user) {
setUser(user)
sessionStorage.setItem("user", JSON.stringify(user))
const uid = user.uid;
console.log("set user")
} else {
}
});
useEffect(() => {
const loggedInUser = sessionStorage.getItem("user");
if (loggedInUser != null) {
const foundUser = loggedInUser.toString();
setUser(foundUser);
console.log(user)
}
}, []);
return (
<div>
<li className="nav-item">
{
(sessionStorage.user ?
<div className="d-flex justify-content-around row">
<Link className="nav-link" to="/user/perfil">Mi cuenta</Link>
</div>
: <Link className="nav-link" to="/login">Iniciar sesión / Registrarse</Link>
)
}
</li>
</div>
)
}
导出默认应用;
我的login.js
const auth = getAuth();
console.log(auth.currentUser);
const loginWithEmailAndPassword = async (email, password) => {
setPersistence(auth, browserSessionPersistence)
.then(() => {
signInWithEmailAndPassword(auth, email, password)
}).catch((error) => {
const errorCode = error.code;
const errorMessage = error.message;
alert(error.message)
})
}
class Login extends Component {
constructor() {
super();
this.state = {
email: "",
password: "",
redirect: "",
};
}
handleChangeEmail = () => {
this.setState({ email: document.getElementById("email").value });
console.log(this.state);
}
handleChangePassword = () => {
this.setState({ password: document.getElementById("password").value })
}
handleRedirect = () => {
this.setState({ redirect: "/aplicacion" });
console.log(this.state);
}
handleClick = async () => {
try {
await loginWithEmailAndPassword(
this.state.email,
this.state.password
);
this.handleRedirect();
} catch (err) {
console.error(err);
alert(err.message);
}
};
render() {
if (this.state.redirect) {
return <Navigate to={this.state.redirect} />
}
return (
<div className="d-flex justify-content-center" >
<div className="col-6">
<Link to='/recuperacion' className="tiny-text">He olvidado mi contraseña</Link>
</div>
</div>
)
}
}
编辑:我目前正在为将位于 App.js 中的应用程序的另一部分开发重定向检测功能,目前它只是一个数组,用于检查最后两条路线是否是与重定向情况相同,这对我来说太过暴力了,但这就是我现在所拥有的。
好的,我最终通过使用状态和挂钩解决了重定向问题让我解释一下:
我创建了一个名为 redirectState 的新状态及其 setter 和一个导航状态:
const [redirectState, setRedirectState] = useState()
let navigate = useNavigate()
然后我只需要在身份验证状态更改时设置它,以便应用程序知道何时重定向以及何时不重定向:
onAuthStateChanged(auth, (user) => {
if (user) {
setUser(user)
sessionStorage.setItem("user", JSON.stringify(user))
const uid = user.uid;
console.log("set user");
console.log(uid)
setRedirectState("redirect")
} else {
sessionStorage.clear();
setRedirectState()
}});
最后我使用了反应路由器 useNavigate 钩子来直接控制重定向:
useEffect(() => {
const loggedInUser = sessionStorage.getItem("user");
console.log("checking user...")
if (loggedInUser != undefined) {
const foundUser = loggedInUser.toString();
setUser(foundUser);
console.log(user);
navigate("/aplicacion")
}else{
console.log("no user")
navigate("/")
}}, [redirectState]);
它可能看起来很粗糙,但功能目前有效,当调用导航功能时所有组件更新,这样应用程序每次都会显示正确的 link,有一些我放错地方的资源想修复,但这将在另一点进行,如果我找到改进其编码方式的方法,将保持此 post 更新。
但现在我认为它已经解决了! :-)