reactjs - 使用 React 和 Gatsby 传递道具
问题描述
我的 Login.js 中有我所有的 firebase 函数和变量,但我的 Dashboard.js 还需要访问其中的两个道具。出于某种原因,无论我尝试什么,我都无法让它工作。因为我使用的是 gatsby,所以它们也是两个不同的页面。
这是我的 Login.js 代码(我想要传递的所有函数都在其中)
import React, { useState, useEffect, Component } from "react";
import "../css/Login.css";
import { Link, navigate } from "gatsby";
import BackGround from "../components/bg";
import Navbar from "../components/navbar";
import fire from "../components/fire";
const Login = () => {
const [user, setUser] = useState("");
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [emailError, setEmailError] = useState("");
const [passwordError, setPasswordError] = useState("");
const [hasAccount, setHasAccount] = useState(false);
const clearInputs = () => {
setEmail("");
setPassword("");
};
const clearErrors = () => {
setEmailError("");
setPasswordError("");
};
const handleLogin = () => {
clearErrors();
fire
.auth()
.signInWithEmailAndPassword(email, password)
.catch((err) => {
switch (err.code) {
case "auth/invalid-email":
case "auth/user-disabled":
case "auth/user-not-found":
setEmailError(err.message);
break;
case "auth/wrong-password":
setPasswordError(err.message);
break;
}
});
};
const handleSignup = () => {
clearErrors();
fire
.auth()
.createUserWithEmailAndPassword(email, password)
.catch((err) => {
switch (err.code) {
case "auth/email-already-in-use":
case "auth/invalid-email":
setEmailError(err.message);
break;
case "auth/weak-password":
setPasswordError(err.message);
break;
}
});
};
const handleLogout = () => {
fire.auth().signOut();
};
const authListener = () => {
fire.auth().onAuthStateChanged((user) => {
if (user) {
clearInputs();
setUser(user);
} else {
setUser("");
}
});
};
useEffect(() => {
authListener();
}, []);
return (
<div>
<BackGround />
<Navbar />
{/* {user
? (navigate("/dashboard", { replace: true }),
(<Dashboard handleLogout={handleLogout} user={user} />))
: null} */}
{user ? <h1>User</h1> : <h1>No user</h1>}
<section className="form-signin">
{hasAccount ? (
<h2 className="form-signin-heading">Login</h2>
) : (
<h2 className="form-signin-heading">Signup</h2>
)}
<label className="control-label form-labels">Email</label>
<input
className="form-input"
placeholder="Enter email"
type="text"
autoFocus
required
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<p className="errorMsg">{emailError}</p>
<label className="control-label form-labels">Password</label>
<input
className="form-input"
placeholder="Enter password"
type="password"
required
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<p className="errorMsg">{passwordError}</p>
{hasAccount ? (
<>
<p className="AHAC">
Not Registered?{" "}
<span onClick={() => setHasAccount(!hasAccount)} className="AHAC">
Create an account.
</span>
</p>
<center>
<button className="form-button" onClick={handleLogin}>
Login
</button>
</center>
</>
) : (
<>
<p className="AHAC">
Already have an account?{" "}
<span className="AHAC" onClick={() => setHasAccount(!hasAccount)}>
Sign In.
</span>
</p>
<center>
<button className="form-button" onClick={handleSignup}>
Signup
</button>
</center>
</>
)}
</section>
</div>
);
};
export default Login;
这是我的 Dashboard.js(需要访问 handleLogout 函数和用户变量)
import { navigate } from "gatsby";
import React from "react";
import BackGround from "../components/bg";
import Navbar from "../components/navbar";
const Dashboard = ({ handleLogout, user }) => {
return (
<div>
<BackGround />
<Navbar />
{/* {user ? null : navigate("/Login")} */}
{user ? <h1>User</h1> : <h1>No user</h1>}
<h1 className="welcome-text">Welcome, User</h1>
<h1 className="page-header">You have generated 100 Facts!</h1>
<center>
<button className="logout-button" onClick={handleLogout}>
Logout
</button>
</center>
</div>
);
};
export default Dashboard;
一如既往,任何帮助将不胜感激,谢谢!
解决方案
您可以使用React Hooks和React Context的组合来实现这一点。是的,您可以将React Context 与 Gatsby 一起使用。看看这个useAuth。您可以以此为基础来构建您自己的自定义钩子。像这样的东西:
创建您的自定义挂钩
const AuthContext = React.createContext();
export function AuthProvider({ children }) {
const auth = useProvideAuth();
return <AuthContext.Provider value={auth}>{children}</AuthContext.Provider>;
}
export const useAuth = () => {
return useContext(authContext);
};
function useProvideAuth() {
//The auth state and methods you need
const [user, setUser] = React.useState("");
const [email, setEmail] = React.useState("");
const [password, setPassword] = React.useState("");
const [emailError, setEmailError] = React.useState("");
const [passwordError, setPasswordError] = React.useState("");
const [hasAccount, setHasAccount] = React.useState(false);
const clearInputs = () => {
//...
};
const clearErrors = () => {
//...
};
const handleLogin = () => {
//...
};
const handleSignup = () => {
//...
};
const handleLogout = () => {
//...
};
const authListener = () => {
//...
};
React.useEffect(() => {
//...
}, []);
return {
user,
handleLogin,
handleLogout,
};
}
在 Gatsby 浏览器文件 (gatsby-browser.js) 中添加提供程序
import React from "react"
import { AuthProvider } from "./src/context/AuthContext"
export const wrapRootElement = ({ element }) => (
<AuthProvider>{element}</AuthProvider>
)
在你的组件中使用它
const Dashboard = ({ handleLogout, user }) => {
const auth = useAuth();
// you can access auth.user, auth.logout
return (
<div>...</div>
);
};
推荐阅读
- testing - 将以太坊从账户转移到合约时“耗尽气体”
- kotlin - 我创建类的对象并得到一个错误“线程“主”java.lang.StackOverflowError中的异常”
- c# - C#8.0:具有默认实现的接口的受保护属性
- javascript - 如何接收用户输入的日期并将其与 date() javascript 函数匹配?
- rust - FnBox 示例抛出错误:盒装中没有 FnBox?
- stripe-payments - 为什么 Stripe checkout Webhooks 会将 customer_email 发送为 null?
- java - 创建输入字符菜单
- python - 并排显示两张 Folium 地图?
- html - 悬停在菜单上显示每个菜单中的下拉菜单列表
- ios - Swift:更改 iOS 13 的状态栏颜色