javascript - React Typescript Log in不发送请求,但重新渲染主要组件

标签 javascript reactjs typescript react-router axios

我在 react 时遇到问题。当我按下登录按钮后,从附加到按钮的函数进行的 axios 调用有时会将请求发送到后端(经过测试以查看是否是来自 spring 的问题,但使用 postman 每次都可以正常工作)但是当从前端发送并不总是到达后端。此外,在前面,它重新渲染并显示 URL 中引入的名称和密码。 有什么想法吗?另外,如果我坚持调用一段时间,它会神奇地改变前端的 url 并在后端正确显示。我在 promise 中遇到了断点,但它从未到达那里。 下面是我的前端,App.tsx、Login.tsx 和 Doctor.tsx。

Login.tsx

import React from 'react';
import './App.css';
import Login from './components/Login';
import CssBaseline from "@material-ui/core/CssBaseline";
import {Route, Switch} from "react-router";
import DoctorMainPage from './components/Doctor';
import {BrowserRouter} from "react-router-dom";


const App: React.FC = () => {
  return (
          <>
                  <BrowserRouter>
                      <Switch>
                          <Route exact path = "/" component={Login}/>
                          <Route exact path = "/doctor" component={DoctorMainPage}/>
                      </Switch>
                  </BrowserRouter>
          </>

  );
};

export default App;
Login.tsx

import React, {useEffect, useState} from 'react';
import Avatar from '@material-ui/core/Avatar';
import Button from '@material-ui/core/Button';
import TextField from '@material-ui/core/TextField';
import FormControlLabel from '@material-ui/core/FormControlLabel';
import Checkbox from '@material-ui/core/Checkbox';
import LockOutlinedIcon from '@material-ui/icons/LockOutlined';
import Typography from '@material-ui/core/Typography';
import { makeStyles } from '@material-ui/core/styles';
import Container from '@material-ui/core/Container';
import {Paper} from "@material-ui/core";
import useRouter from "use-react-router";
import appState from "../store/state";
import actions from "../actions/actions";
import axios from 'axios';
import {observer} from "mobx-react";


const useStyles = makeStyles(theme => ({
    '@global': {
        body: {
            backgroundColor: theme.palette.common.white,
        },
    },
    paper: {
        marginTop: theme.spacing(8),
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'center',
    },
    avatar: {
        margin: theme.spacing(1),
        backgroundColor: theme.palette.secondary.main,
    },
    form: {
        width: '100%', // Fix IE 11 issue.
        marginTop: theme.spacing(1),
    },
    submit: {
        margin: theme.spacing(3, 0, 2)
    },
}));

const SignIn = (function SignIn() {

    useEffect(() =>
        {
            setPassword("");
            setUsername("");
        },
        []
    );

    debugger;
    const login = () => {
        debugger;
      axios.post("http://localhost:8080/login", {
          username: username,
          password: password
      }).then((response) => {
          debugger;
          console.log(response.data);
          history.push("/doctor");
      });
    };

    const {history, location, match} = useRouter();
    const classes = useStyles();
    const [username, setUsername] = useState("");
    const [password, setPassword] = useState("");
    const isValid = () => {
        return username.length > 0 && password.length > 0
    };
    return (
        <>


            <Container component="main" maxWidth="xs">

                <Paper className={classes.paper}>
                    <Avatar className={classes.avatar}>
                        <LockOutlinedIcon />
                    </Avatar>
                    <Typography component="h1" variant="h5">
                        Sign in
                    </Typography>
                    <form className={classes.form} noValidate>
                        <TextField onChange={(e) => setUsername(e.target.value)}
                                   variant="outlined"
                                   margin="normal"
                                   required
                                   fullWidth
                                   id="username"
                                   label="Username"
                                   name="username"
                                   autoComplete="username"
                                   autoFocus
                        />
                        <TextField onChange={(e) => setPassword(e.target.value)}
                                   variant="outlined"
                                   margin="normal"
                                   required
                                   fullWidth
                                   name="password"
                                   label="Password"
                                   type="password"
                                   id="password"
                                   autoComplete="current-password"
                        />
                        <FormControlLabel
                            control={<Checkbox value="remember" color="primary" />}
                            label="Remember me"
                        />
                        <Button disabled={!isValid()} onClick={() => login()}
                                type="submit"
                                fullWidth
                                variant="contained"
                                color="primary"
                                className={classes.submit}
                        >
                            Sign In
                        </Button>
                    </form>
                </Paper>
            </Container>

        </>

    );
});

export default SignIn;
Doctor.tsx


import AppBarWithMenu from './AppBarWithMenu';
import {Paper} from "@material-ui/core";
import * as React from "react";
import PacientsTable from './Table';
import appState from "../store/state";
import {observer} from "mobx-react";
import Button from "@material-ui/core/Button";
import useRouter from "use-react-router";
import {useEffect} from "react";
import useReactRouter from 'use-react-router';

const DoctorMainPage = observer(function DoctorMainPage(){

    const {history, location, match} = useReactRouter();

    return (
        <Paper>
            <AppBarWithMenu/>
            <PacientsTable/>
            <Button onClick={() => history.push("/")}>
                Logout
            </Button>
        </Paper>
    );
});

export default DoctorMainPage;

Username and password appears top, in the url

最佳答案

发生这种情况是因为您的 Login.tsx 文件中定义的表单已提交。

Html 表单是在 Web 应用程序中触发请求的另一种较旧的方式。与 AJAX 调用(例如您尝试使用 axios 进行的调用)不同,表单提交会导致浏览器加载新页面,因此您的所有 JS 上下文都会丢失。

Html 表单有一个 action(执行请求的 URL)和一个 method(用于执行请求的 HTTP 方法)。 action 默认为当前 URL,而 method 默认为 GET(也可以是 POST) .

这些表单可用于随请求发送数据。这些值取自 form 标记内的输入字段。通过 GET 表单提交,数据通过 URL 参数发送。每个参数名称均取自每个包含的输入字段的 name 属性。

所有这些都解释了为什么您的应用程序会在您单击按钮时重新加载页面,因为表单已提交,导致在/URL 上发出 GET 请求,并在 URL 中包含用户名和密码参数。 onClick 事件永远不会被触发,因此 login 函数永远不会被调用,因为页面正在重新加载(因此 JS 上下文消失了)。

要防止这种情况,只需将按钮类型从 submit 更改为 button 或执行 preventDefault调用在 onClick 事件中接收到的事件对象。

关于javascript - React Typescript Log in不发送请求,但重新渲染主要组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58416502/

相关文章:

javascript - Bootstrap 2.3.2 导航栏选择项

javascript - 通过继承 React.js 中的值来更改复选框的值

Angular2如何在另一个组件中使用一个组件的功能

javascript - 在 javascript/typescript 中将 Element 转换为 HTMLElement

javascript - 使用<noscript>有安全风险吗?

javascript - jsxgraph:如何更新线的点?

javascript - 来自多个 ajax 请求的求和值

reactjs - 如何使用 native react 在选项卡导航下的页脚文本中设置图像

reactjs - Expo React Native App + Redux-Persist : AsyncStorage Problem

javascript - angular2 在具有自定义可序列化对象的后台线程中工作