Я довольно новичок в React, но я ломал голову над различными способами создания PrivateRoute весь день и не смог выяснить, как правильно аутентифицировать пользователя через мою форму входа.
Ниже приведен код моей маршрутизации, а также класс Login и функция PrivateRoutes (содержится в отдельном файле). Я подозреваю, что проблема, скорее всего, связана с моим отсутствием понимания относительно реквизита против переменных состояния и которое может быть передано родительским классам.
Вот файл маршрутизации:
import React, {Component} from 'react';
import './Style.css';
import ReactDOM from 'react-dom';
import {BrowserRouter, Route, Redirect, Switch} from 'react-router-dom';
import PublicLanding from './Pages/PublicLanding'
import AllClasses from './Pages/AllClasses'
import Classes from './Pages/Classes'
import Schools from './Pages/Schools'
import Home from './Pages/Home'
import Signup from './Pages/Signup'
import Login from './Pages/Login'
import NotFound from './Pages/NotFound'
import PrivateRoute from './Pages/PrivateRoute'
class App extends Component {
render() {
return(
<BrowserRouter>
<Switch>
<Route exact path='/' component={PublicLanding}/>
<Route exact path='/signup' render={() => (
<Signup/>
)}/>
<Route exact path='/login' render={() => (
<Login/>
)}/>
<Route exact path='/schools' render={() => (
<Schools/>
)}/>
<Route exact path='/classes' render={() => (
<AllClasses/>
)}/>
<Route exact path='/classes/:course_code' render={() => (
<Classes/>
)}/>
<PrivateRoute exact path="/dashboard" component={Home}/>
//generic path to render if none of the other work
<Route path='*' render={() => (
<NotFound/>
)} />
</Switch>
</BrowserRouter>
)
}
}
export default App;
Это класс входа в систему:
import React, { Component } from 'react';
import { Switch, Route, Redirect } from 'react-router-dom';
import PrivateRoute from './PrivateRoute'
class Login extends Component {
constructor(props) {
super(props);
this.state = {
email: '',
password: '',
isEmail: false,
warningText: '',
invalidReason: '',
isAuth: false
};
}
login = () => {
// make sure it's a valid email before checking the database
if (this.state.isEmail) {
var details = {
'email': this.state.email,
'password': this.state.password
};
const formBody = Object.keys(details).map(key => encodeURIComponent(key) + '=' + encodeURIComponent(details[key])).join('&'); // Putting json into acceptable format to be read
fetch('http://localhost:8888/authenticate', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
},
body: formBody
}).then((response) => response.json())
.then((responseJson) => {
if(responseJson.page === "Home"){
this.setState({
isAuth: true
});
} else {
this.setState({invalidReason: responseJson.error}, () => {
this.invalidAuthentication();
});
}
});
} else {
if (this.state.email + this.state.password === '') {
this.setState({invalidReason: 'You need to enter a username and password'}, () => {
this.invalidAuthentication();
});
} else {
this.setState({invalidReason: 'Your credentials are incorrect.'}, () => {
this.invalidAuthentication();
});
}
}
}
invalidAuthentication = () => {
alert(
this.state.invalidReason,
[
{text: 'Ok'},
],
{cancelable: false},
);
}
invalidEmail = () => {
this.setState({
warningText: "Please enter a valid official school email address."
})
}
verify = (email) => {
this.setState({
email:email
});
let reg = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})/;
if (reg.test(email) === false){
this.invalidEmail();
} else {
this.setState({
isEmail: true,
warningText: ''
});
}
}
render() {
if(this.state.isAuth) return (
<PrivateRoute to="/dashboard" auth={this.state.isAuth}/>
);
return (
<div className="render-events">
<h1>Login</h1>
<label>
Username:
<input type="text" placeholder="email@school.edu" onChange={(text) => this.verify(text.target.value)}/>
</label>
<label>
Password:
<input type="text" securetextentry="true" onChange={(text) => this.setState({password:text.target.value})}/>
</label>
<button onClick={() => this.login()}>
Login
</button>
</div>
);
}
}
export default Login;
И, наконец, вот функция PrivateRoutes:
import React from 'react'
import { Route, Redirect } from 'react-router-dom';
const PrivateRoute = ({ component: Component, ...rest }) => (
(props) => (
<Route
render={(props) =>
props.isAuth === true ? <Component {...props} /> : <Redirect to="/login" />
}
/>
)
)
export default PrivateRoute;
Я был бы очень признателен за помощь в этом, поскольку я не нашел исчерпывающего объяснения того, как а) создать функцию входа в систему на экране маршрутизации (которая кажется неэффективной) или б) передать реквизит isAuth обратно. до моих маршрутов.
Заранее спасибо!