簡體   English   中英

帶有自定義 Hook 的登錄表單 React JS

[英]Login Form React JS With Custom Hook

我目前正在學習 React JS。 教程 DO我之前已經有一個 PHP 后端,我想創建一個登錄表單,其中后端的結果是 JWT。 為此,我在 React JS 中使用了一個自定義鈎子。 這是我創建的代碼。

應用程序.js

import "./App.css";
import React from "react";
import { Routes } from "../config";
import { useToken } from "../hooks";
import Login from "./Login";

const App = () => {

  const { token, setToken } = useToken();

  if (!token) {
    return <Login setToken={setToken} />;
  }

  return <Routes />;
};
export default App;

使用令牌()

import { useState } from "react";

export default function useToken() {
  const getToken = () => {
    const tokenString = localStorage.getItem("token");
    const userToken = JSON.parse(tokenString);
    return userToken?.token;
  };

  const [token, setToken] = useState(getToken());

  const saveToken = (userToken) => {
    localStorage.setItem("token", JSON.stringify(userToken));
    setToken(userToken.token);
  };

  return {
    setToken: saveToken,
    token,
  };
}

登錄/index.js

import React, { useState } from "react";
import PropTypes from "prop-types";
import { Button, Card, Col, Container, Form, Row } from "react-bootstrap";
import "./login.css";

async function loginUser(credentials) {
  const url = "v1/auth";
  const user = new FormData();
  user.append("username", credentials.username);
  user.append("password", credentials.password);

  return fetch(url, {
    method: "POST",
    body: user,
  }).then((data) => data.json());
}

export default function Login({ setToken }) {
  const [username, setUserName] = useState();
  const [password, setPassword] = useState();

  // Handle submit
  const handleSubmit = async (e) => {
    e.preventDefault();
    const token = await loginUser({ username, password });
    setToken(token);
  };

  return (
    <div id="login-page">
      <Container>
        <Row className="d-flex justify-content-md-center align-items-center vh-100">
          <Col sm={12} md={6}>
            <Card>
              <Form onSubmit={handleSubmit}>
                <Card.Header>Sign In</Card.Header>
                <Card.Body>
                  <Form.Group controlId="loginform-username">
                    <Form.Label>Username</Form.Label>
                    <Form.Control
                      type="text"
                      placeholder="Username"
                      name="username"
                      onChange={(e) => setUserName(e.target.value)}
                    />
                  </Form.Group>

                  <Form.Group controlId="loginform-password">
                    <Form.Label>Password</Form.Label>
                    <Form.Control
                      name="password"
                      type="password"
                      placeholder="Password"
                      onChange={(e) => setPassword(e.target.value)}
                    />
                  </Form.Group>
                </Card.Body>
                <Card.Footer>
                  <Button
                    variant="primary"
                    type="submit"
                    className="float-right"
                  >
                    Login
                  </Button>
                  <div className="clearfix"></div>
                </Card.Footer>
              </Form>
            </Card>
          </Col>
        </Row>
      </Container>
    </div>
  );
}

Login.propTypes = {
  setToken: PropTypes.func.isRequired,
};

成功登錄后,我將令牌保存到本地存儲。 但我收到以下警告。

index.js:1 Warning: Failed prop type: The prop `setToken` is marked as required in `Login`, but its value is `undefined`.

如何解決這個問題? 非常感謝任何幫助

更新

路線

import React from "react";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import { Login, Home } from "../../pages";

const Routes = () => {
  return (
    <Router>
      <Switch>
        <Route path="/login">
          <Login />
        </Route>

        <Route path="/">
          <Home />
        </Route>
      </Switch>
    </Router>
  );
};

export default Routes;

Routes中,您調用Login但從不傳遞它setToken ,這是必需的。 一種選擇是通過Routes傳遞setToken function :

應用程序.js

import "./App.css";
import React from "react";
import { Routes } from "../config";
import { useToken } from "../hooks";
import Login from "./Login";

const App = () => {

  const { token, setToken } = useToken();

  if (!token) {
    return <Login setToken={setToken} />;
  }

  return <Routes setToken={setToken} />;
};
export default App;

路由.js

import React from "react";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import { Login, Home } from "../../pages";

const Routes = ({ setToken }) => {
  return (
    <Router>
      <Switch>
        <Route path="/login">
          <Login setToken={setToken} />
        </Route>

        <Route path="/">
          <Home />
        </Route>
      </Switch>
    </Router>
  );
};

export default Routes;
<Route path="/login">
          <Login /> /* <--- this line is calling Login component but is passing setToken as undefined */
</Route>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM