Мои компоненты отображаются с данными с сервера, если маршрут не защищен. Как только я защищаю маршрут, this.props
возвращает неопределенное значение.
Приложение. js
import React, { Component } from 'react';
import {Route, withRouter} from 'react-router-dom';
import auth0Client from './Auth/Auth';
import NavBar from './NavBar/NavBar';
import Callback from './Callback/Callback';
import Customers from './Customers/Customers';
import Customer from './Customer/Customer';
import SecuredRoute from './SecuredRoute/SecuredRoute';
class App extends Component {
constructor(props) {
super(props);
this.state = {
checkingSession: true,
}
}
async componentDidMount() {
if (this.props.location.pathname === '/callback') {
this.setState({checkingSession:false});
return;
}
try {
await auth0Client.silentAuth();
this.forceUpdate();
} catch (err) {
if (err.error !== 'login_required') console.log(err.error);
}
this.setState({checkingSession:false});
}
render() {
return (
<div>
<NavBar/>
<Route exact path='/callback' component={Callback}/>
<SecuredRoute exact path='/customers'
component={CustomersComponent}
checkingSession={this.state.checkingSession}
/>
<SecuredRoute exact path='/customers/:customerId'
component={CustomerComponent}
checkingSession={this.state.checkingSession}
/>
{/*<Route exact path='/customers/:customerId' component={CustomerComponent}/>*/} // this works
</div>
);
}
}
const CustomersComponent = (props) => {
return (
<Customers {...props}
/>
);
}
const CustomerComponent = (props) => {
return (
<Customer {...props}
/>
);
}
export default withRouter(App);
Auth. js
import auth0 from 'auth0-js';
class Auth {
constructor() {
this.auth0 = new auth0.WebAuth({
domain: 'domain.eu.auth0.com',
audience: 'https://domain.eu.auth0.com/userinfo',
clientID: 'clientID',
redirectUri: 'http://localhost:3000/callback',
responseType: 'id_token',
scope: 'openid profile'
});
this.getProfile = this.getProfile.bind(this);
this.handleAuthentication = this.handleAuthentication.bind(this);
this.isAuthenticated = this.isAuthenticated.bind(this);
this.signIn = this.signIn.bind(this);
this.signOut = this.signOut.bind(this);
}
getProfile() {
return this.profile;
}
getIdToken() {
return this.idToken;
}
isAuthenticated() {
return new Date().getTime() < this.expiresAt;
}
signIn() {
this.auth0.authorize();
}
handleAuthentication() {
return new Promise((resolve, reject) => {
this.auth0.parseHash((err, authResult) => {
if (err) return reject(err);
if (!authResult || !authResult.idToken) {
return reject(err);
}
this.setSession(authResult);
resolve();
});
})
}
setSession(authResult) {
this.idToken = authResult.idToken;
this.profile = authResult.idTokenPayload;
// set the time that the id token will expire at
this.expiresAt = authResult.idTokenPayload.exp * 1000;
}
signOut() {
this.auth0.logout({
returnTo: 'http://localhost:3000',
clientID: 'clientID',
});
}
silentAuth() {
return new Promise((resolve, reject) => {
this.auth0.checkSession({}, (err, authResult) => {
if (err) return reject(err);
this.setSession(authResult);
resolve();
});
});
}
}
const auth0Client = new Auth();
export default auth0Client;
Клиенты. js
import React, {Component} from 'react';
import {Link} from 'react-router-dom';
import axios from 'axios';
class Customers extends Component {
constructor(props) {
super(props);
this.state = {
accounts: null,
customers: null
};
}
async componentDidMount() {
const customers = (await axios.get('http://localhost:8081/customers/')).data;
const accounts = (await axios.get('http://localhost:8081/accounts/')).data;
this.setState({
accounts,
customers
});
}
countAccounts(custid) {
const accounts = this.state.accounts;
let count = 0;
accounts.forEach(function(element) {
if (element.CustomerId === custid) {
count = count + 1;
}
});
return count;
}
countOverdueAccounts(custid) {
const accounts = this.state.accounts;
let count = 0;
accounts.forEach(function(element) {
if (element.CustomerId === custid && element.CurrentStatus !== "Active") {
count = count + 1;
}
});
return count;
}
listOfAccounts(custid) {
const accounts = this.state.accounts;
let arr = [];
accounts.forEach(function(element) {
if (element.CustomerId === custid) {
arr.push(<p key={element.id}>{element.AccountNumber}</p>)
}
});
return arr;
}
overdueCard(custid) {
const accounts = this.state.accounts;
let cardTheme = "card text-white bg-primary mb-3";
accounts.forEach(function(element) {
if (element.CustomerId === custid && element.CurrentStatus !== "Active") {
cardTheme = "card text-white bg-danger mb-3";
}
});
return cardTheme;
}
render() {
return (
<div className="container">
<div className="row">
{this.state.customers === null && <p>Loading customer records...</p>}
{
this.state.customers && this.state.customers.map(customer => (
<div key={customer.id} className="col-sm-12 col-md-4 col-lg-3">
<Link to={`/customers/${customer.id}`}>
<div className={this.overdueCard(customer.id)}>
<div className="card-header">
<p>Accounts: {this.countAccounts(customer.id)}</p>
<p>Overdue accounts: {this.countOverdueAccounts(customer.id)}</p>
</div>
<div className="card-body">
<h4 className="card-title">Current status: {customer.CurrentStatus}</h4>
<p className="card-text">{customer.FirstName} {customer.Surname}</p>
<p className="card-text">ID number: {customer.NationalIDNumber}</p>
<p className="card-text">Contact number: {customer.ContactNumber}</p>
<p className="card-text">Email: {customer.EmailAddress}</p>
<div className="card-text">List of accounts:{this.listOfAccounts(customer.id)}</div>
</div>
</div>
</Link>
</div>
))
}
</div>
</div>
)
}
}
export default Customers;
Клиент. js
import React, {Component} from 'react';
import axios from 'axios';
import SubmitUpdate from './SubmitUpdate';
import auth0Client from '../Auth/Auth';
class Customer extends Component {
constructor(props) {
super(props);
this.state = {
account: null,
customer: null
};
this.submitUpdate = this.submitUpdate.bind(this);
}
async componentDidMount() {
await this.refreshCollection();
}
async refreshCollection() {
//console.log('this.props: ', this.props);
const { match: { params } } = this.props; // <----- fails here as this.props is not returned
//console.log(`http://localhost:8081/customers/${params.customerId}`);
const customer = (await axios.get(`http://localhost:8081/customers/${params.customerId}`)).data;
const account = (await axios.get(`http://localhost:8081/accounts/${params.customerId}`)).data;
this.setState({
account: account,
customer: customer
});
}
async submitUpdate(update){
await axios.post(`http://localhost:8081/update/${this.state.customer.id}`, {
update,
}, {
headers: { 'Authorization': `Bearer ${auth0Client.getIdToken()}` }
});
await this.refreshCollection();
}
render() {
const {customer} = this.state;
const {account} = this.state;
//console.log('customer: ', customer);
//console.log('account: ', account);
if (customer === null) return <p>Loading... </p>;
return (
<div className="container">
<div className="row">
<div className="jumbotron col-12">
<p className="card-text">{customer[0].FirstName} {customer.Surname}</p>
<p className="card-text">ID number: {customer[0].NationalIDNumber}</p>
<p className="card-text">Contact number: {customer[0].ContactNumber}</p>
<p className="card-text">Email: {customer[0].EmailAddress}</p>
<hr className="my-4" />
<SubmitUpdate accountId={customer.id} submitUpdate={this.submitUpdate} />
<p>Notes</p>
</div>
</div>
</div>
);
}
}
export default Customer;
SecuredRoute. js
import React from 'react';
import {Route} from 'react-router-dom';
import auth0Client from '../Auth/Auth';
function SecuredRoute(props) {
const {component: Component, path, checkingSession} = props;
return (
<Route path={path} render={() => {
if (checkingSession) return <h3 className="text-center">Validating session...</h3>;
if (!auth0Client.isAuthenticated()) {
auth0Client.signIn();
return <div></div>;
}
return <Component />
}} />
);
}
export default SecuredRoute;
Пожалуйста, помогите мне понять, что я делаю неправильно , Я уверен, что это что-то простое, я просто не могу понять это.