Визуализировать навигацию после входа - PullRequest
0 голосов
/ 25 октября 2019

Я работаю над проектом реагирования. В настоящее время я пытаюсь снова отобразить навигацию после входа в систему, чтобы показать ссылки, которые видны только зарегистрированным пользователям. Следующий код работает нормально, а также перенаправление идет в «/».

Основная проблема заключается в том, что ссылки для вошедших в систему пользователей видны только после перезагрузки страницы.

Nav.js

import React, {Component} from "react";
import {Nav, Navbar} from 'react-bootstrap';
import { Auth } from 'aws-amplify'
import SignIn from "./Authentication/SignIn";
import SignUp from "./Authentication/SignUp";
import SignOut from "./Authentication/SignOut";
import {
    BrowserRouter as Router,
    withRouter,
    Redirect,
    Switch,
    Route,
    Link
} from "react-router-dom";

import Share from "./Share";
import Subscribe from "./Subscribe";
import Home from "./Home"

class PrivateRoute extends React.Component {

    constructor (props) {
        super(props);
        this.state = {
            loaded: false,
            isAuthenticated: false
        }
    }

    componentDidMount() {
        this.authenticate()
        this.unlisten = this.props.history.listen(() => {
            Auth.currentAuthenticatedUser()
                .then(user => console.log('user: ', user))
                .catch(() => {
                    if (this.state.isAuthenticated) this.setState({ isAuthenticated: false })
                })
            });
        }

        componentWillUnmount() {
            this.unlisten()
        }

        authenticate() {
        Auth.currentAuthenticatedUser()
            .then(() => {
                this.setState({ loaded: true, isAuthenticated: true});
            })
            .catch(() => this.props.history.push('/signup'))
        }

    render() {
        const { component: Component, ...rest } = this.props
        const { loaded , isAuthenticated} = this.state
        if (!loaded) return null
        return (
            <Route
                {...rest}
                render={props => {
                    return isAuthenticated ? (
                        <Component {...props} />
                    ) : (
                        <Redirect
                            to={{
                                pathname: "/signup",
                            }}
                        />
                    )
                }}
            />
        )
    }
}

PrivateRoute = withRouter(PrivateRoute)

class Routes extends React.Component {

    constructor (props) {
        super(props);
        this.state = {
            showItemInMenu: false
        }
    }

    componentDidMount() {
         Auth.currentAuthenticatedUser()
                .then(() => { this.setState({showItemInMenu: true })})
                .catch(() => { this.setState({showItemInMenu: false})});
        }

    render() {
        const showItemInMenu = this.state.showItemInMenu
        return (

            <Router>
                <Navbar bg="dark" variant="dark">
                    <Navbar.Brand as={Link} to="/">Todo</Navbar.Brand>
                    <Navbar.Toggle aria-controls="basic-navbar-nav"/>
                    <Navbar.Collapse id="basic-navbar-nav">
                        <Nav className="ml-auto">
                            <Nav.Link as={Link} to="/">Home</Nav.Link>
                            {showItemInMenu &&  <Nav.Link as={Link} to="/share" >Share</Nav.Link>}
                            {showItemInMenu &&  <Nav.Link as={Link} to="/subscribe" >Subscribe</Nav.Link> }
                            {showItemInMenu &&  <Nav.Link as={Link} to="/signout" >Logout</Nav.Link> }
                            <Nav.Link as={Link} to="/signup" >Registration</Nav.Link>
                            <Nav.Link as={Link} to="/signin" >Login</Nav.Link>
                        </Nav>
                    </Navbar.Collapse>
                </Navbar>
                <Switch>
                    <Route exact path='/'  component={Home}/>
                    <Route path='/signup' component={SignUp}/>
                    <Route path='/signin' component={SignIn}/>
                    <PrivateRoute path='/share' component={Share}/>
                    <PrivateRoute path='/subscribe' component={Subscribe}/>
                    <PrivateRoute path='/signout' component={SignOut}/>
                </Switch>
            </Router>
        )
    }
}

export default Routes

Signin.js

import React, { Component } from "react";
import { Form, Row, Col,Button, Alert,Container } from 'react-bootstrap';
import { Auth } from "aws-amplify";
import styled from 'styled-components';
import { Redirect } from 'react-router-dom'
class SignIn extends Component {

    constructor (props) {
        super(props);
        this.state = {
            username: '',
            password: '',
            message: '',
            redirect: false
        };
        this.handleChange = this.handleChange.bind(this);
        this.handleSignIn = this.handleSignIn.bind(this);
    }

    handleChange (event) {
        this.setState({ [event.target.name]: event.target.value });
    }

    handleSignIn (event){
        event.preventDefault();

        const username = this.state.username;
        const password = this.state.password;
        // You can pass an object which has the username, password and validationData which is sent to a PreAuthentication Lambda trigger
        Auth.signIn({
            username,
            password
        })
            .then(user => console.log(user))
            .then(() => { this.setState({ redirect: true })
        })
            .catch(err =>
                this.setState({message: err.message})
            );

    };

    renderRedirect = () => {
        if (this.state.redirect) {
            return <Redirect
                to={{
                    pathname: "/",
                    state: { fromlogin: true }
                }}
            />

        }
    }

    render () {
        const Title = styled.div`
            margin-top: 10px;
            margin-bottom: 15px;
        `;

        return (
            <Container>
            <Row>
                <Col md={6}>
                    <Title>
                        <h3>Login Form</h3>
                    </Title>
                    <Form onSubmit={this.handleSignIn}>
                        <Form.Group>
                            <Form.Control type="text" name="username"  placeholder="Username" onChange={this.handleChange} />
                        </Form.Group>
                        <Form.Group>
                            <Form.Control type="password" name="password" placeholder="Password" onChange={this.handleChange} />
                        </Form.Group>
                        <Form.Group>
                            <Button
                                variant="primary"
                                type="submit"
                                value="SIGN IN"
                            >LOGIN</Button>
                        </Form.Group>
                    </Form>

                    {this.state.message ?
                        <Alert variant="danger">{this.state.message}</Alert>
                        : <></>}
                </Col>
            </Row>
                {this.renderRedirect()}
            </Container>

        );
    }
}

export default SignIn
...