在子组件中反应登录身份验证

时间:2018-09-07 11:22:14

标签: javascript reactjs react-router-v4

我有一个App组件,用户登录到应用程序后,其余组件必须在呈现前验证身份验证保护,否则重定向到登录页面,即App组件。

我正在尝试通过PrivateRouter将状态变量从App组件传递到子组件,作为我的身份验证保护。但是它不起作用。在此之前,我还尝试使用react-router v4在路由内使用render。

App.js

import React, { Component } from 'react';
import axios from 'axios';
import history from './History';
import './App.css';

class App extends Component {

constructor(){
    super();
    this.state = {
      username: '',
      password: '',
      authenticated: false
    };

  this.handleUserChange = this.handleUserChange.bind(this);
  this.handleSubmit = this.handleSubmit.bind(this);
}


handleSubmit(event){
    event.preventDefault();
    axios.post('https://api.github.com/user',{}, {
      auth: {
        username: this.state.username,
        password: this.state.password
      }
    }).then((response) => {
      console.log(response.data);
      this.setState({
        authenticated : true,
      });
      history.push({pathname: '/home', state: { detail: response.data }});
      history.go('/home');
    }).catch(function(error) {
      this.setState({
        authenticated : false,
      });
      console.log('Error on Authentication' + error);
  });
}

handleUserChange(event){
    this.setState({
      username : event.target.value,
    });
}

handlePasswordChange = event => {
  this.setState({
    password: event.target.value
  });
}

render() {
    return (
      <div className='loginForm'>
        <form onSubmit={this.handleSubmit}>
          <label>
            username :
            <input type="text" value={this.state.username} onChange={this.handleUserChange} required/>
          </label>
          <label>
            password :
            <input type="password" value={this.state.password} onChange={this.handlePasswordChange} required/>
          </label>
          <input type="submit" value="LogIn" />
        </form>
      </div>
    );
  }
}

export default App;

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import PrivateRoute from './PrivateRoute';

import {
  Router,
  Redirect,
  Route,
  Switch
} from "react-router-dom";
import Home from './Home';
import User from './User';
import history from './History';

ReactDOM.render(
<Router history={history}>
  <Switch>
    <Route path="/" exact component={App} />
    <PrivateRoute path="/home" component={Home} />
    <PrivateRoute path="/user" component={User} />
 </Switch>
</Router>,
  document.getElementById('root'));
registerServiceWorker();

Home.js

import React, { Component } from 'react';
import axios from 'axios';
import Autosuggest from 'react-autosuggest';
import './Home.css';
import history from './History';


// When suggestion is clicked, Autosuggest needs to populate the input
// based on the clicked suggestion. Teach Autosuggest how to calculate the
// input value for every given suggestion.
const getSuggestionValue = suggestion => suggestion;

// Use your imagination to render suggestions.
const renderSuggestion = suggestion => (
  <div>
    {suggestion}
  </div>
);

class Home extends Component {
  constructor(props) {
    super(props);

    // Autosuggest is a controlled component.
    // This means that you need to provide an input value
    // and an onChange handler that updates this value (see below).
    // Suggestions also need to be provided to the Autosuggest,
    // and they are initially empty because the Autosuggest is closed.
    this.state = {
      value: '',
      suggestions: [],
      timeout: 0
    };
  }

  onChange = (event, { newValue }) => {
    this.setState({
      value: newValue
    });
   console.log('=====++++ ' + newValue);
  };

  onSuggestionSelected = (event, { suggestion, suggestionValue, suggestionIndex, sectionIndex, method }) => {
    console.log("Get the user +++++++++ " + suggestionValue);
   if(suggestionValue && suggestionValue.length >= 1){
       axios.get('https://api.github.com/users/'+ suggestionValue)
       .then((response) => {
          console.log("user selected : "+ response.data.avatar_url);
          history.push({pathname: '/user', state: { detail: response.data }});
          history.go('/user');
       }).catch(function(error) {
          console.log('Error on Authentication' + error);
        });
     }
  };

  // Autosuggest will call this function every time you need to update suggestions.
  // You already implemented this logic above, so just use it.
  onSuggestionsFetchRequested = ({ value }) => {
    if(this.timeout) clearTimeout(this.timeout);
    this.timeout = setTimeout(() => {
        this.getSuggestions();
      }, 500);
  };

getSuggestions = () =>{
  if(this.state.value && this.state.value.length >= 1){
  axios.get('https://api.github.com/search/users',{
    params: {
      q: this.state.value,
      in:'login',
      type:'Users'
    }
  }).then((response) => {
      console.log("users login : "+ response.data.items);
      const userNames = response.data.items.map(item => item.login);
      console.log("===== " + userNames);
        this.setState({
          suggestions: userNames
        })
  }).catch(function(error) {
    console.log('Error on Authentication' + error);
   });
 }
};

  // Autosuggest will call this function every time you need to clear suggestions.
  onSuggestionsClearRequested = () => {
    this.setState({
      suggestions: []
    });
  };


  render(){

    const { value, suggestions } = this.state;

    // Autosuggest will pass through all these props to the input.
    const inputProps = {
      placeholder: 'Type a userName',
      value,
      onChange: this.onChange
    };

    return (
      <div>
      <div>
        Home page {this.props.location.state.detail.login}
      </div>
      <div>
          <Autosuggest
            suggestions={suggestions}
            onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
            onSuggestionsClearRequested={this.onSuggestionsClearRequested}
            getSuggestionValue={getSuggestionValue}
            renderSuggestion={renderSuggestion}
            inputProps={inputProps}
            onSuggestionSelected={this.onSuggestionSelected}
          />
      </div>
    </div>
    );
}
}

export default Home;

PrivateRouter.js

import React from 'react';
import {
  Redirect,
  Route,
  } from "react-router-dom";



const PrivateRoute = ({ component: Component, ...rest }) => (
  <Route
    {...rest}
    render={props =>
      props.authenticated ? (
        <Component {...props} />
      ) : (
        <Redirect
          to={{
            pathname: "/",
            state: { from: props.location }
          }}
        />
      )
    }
  />
);

export default PrivateRoute;

如何将状态变量authenticated传递给PrivateRouter还是有更好的方法呢?

0 个答案:

没有答案