javascript - 带有自定义 Hook 的登录表单 React JS
问题描述
我目前正在学习 React JS。教程 我之前已经有一个 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
,这是必需的。一种选择是将setToken
函数向下传递Routes
:
应用程序.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;
推荐阅读
- php - 实时服务器上的 SMTP 连接失败 PhpMailer
- gcc - 使用 bazel 构建库并将依赖项硬编码到其中
- cmake - CMake 错误:文件系统错误删除失败:设备或资源忙
- java - 如何防止 Thymleaf 对我的模板进行 urlencoding?
- sonarqube - SonarQube:企业与社区
- floating-point - 将 IEEE 754 的浮点数转换为十六进制的最简单方法
- ssas - SSAS 计算的成员聚合问题
- openlayers-3 - 功能标签在较低的缩放级别消失,我想强制它们始终出现
- vue.js - VueJS Google 图表未加载
- java - 消费者之间的kafka消息分发