首页 > 解决方案 > 使用 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;

一如既往,任何帮助将不胜感激,谢谢!

标签: reactjsgatsbyreact-props

解决方案


您可以使用React HooksReact 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>
  );
};

推荐阅读