вызов mapDispatchToProps внутри axios успех не работает - PullRequest
0 голосов
/ 12 сентября 2018

Я пытаюсь перейти на другую страницу после успешного вызова Axios, который отправляет действие для изменения состояния. Но я уверен, что я неправильно вызвал диспетчеризацию в вызове axios, что приводит к ошибке ниже. Я пробовал много других способов, таких как использование функции стрелки ES6 для вызова метода диспетчеризации, но никогда не работал.

Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.

App.js

import React, { Component } from 'react';
import axios from 'axios';
import history from './History';
import { Redirect } from "react-router-dom";
import './App.css';
import { connect } from 'react-redux';
import * as actionType from './reducer/action';

class App extends Component {

constructor(){
    super();
    this.state = {
        username: '',
        password: '',
        loginData: []
    };

  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.props.onLoginAuth(true);// This is where i am getting ERROR
      //history.push({pathname: '/home', state: { detail: response.data }});
      //history.go('/home');
      this.setState({
        loginData : response.data,
      });
    }).catch(function(error) {
      console.log('Error on Authentication' + error);
  });
}

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

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



render() {
    if(this.props.authenticated){
      console.log("Redirecting to Home page " + this.props.authenticated);
      return <Redirect to={{ pathname: '/home', state: { detail: this.state.loginData } }}/>
    }
    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>
    );
  }
}

const mapStateToProps = state => {
  return {
    authenticated: state.authenticated
  };
}

const mapDispatchToProps = dispatch => {
  return {
    onLoginAuth: (authenticated) => dispatch({type: actionType.AUTH_LOGIN, authenticated:authenticated})
  };
}

export default connect(mapStateToProps, mapDispatchToProps)(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 { Provider } from 'react-redux';
import { createStore } from 'redux';

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

const store = createStore(reducer);

ReactDOM.render(
<Provider store= {store} >
  <Router history={history}>
    <Switch>
      <Route path="/" exact component={App} />
      <PrivateRoute path="/home" component={Home} />
      <PrivateRoute path="/user" component={User} />
   </Switch>
  </Router>
</Provider>,
  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;

enter image description here

Можете ли вы помочь мне, как я могу позвонить onLoginAuth с Axios?

1 Ответ

0 голосов
/ 12 сентября 2018

Не думаю, что проблема в вызове axios.Ваши аксиосы ​​вызывают диспетчеризацию, которая обновляет состояние authenticated .Поэтому каждый раз, когда обновляется состояние authenticated , вызывается метод render компонента App .

Условие if(this.props.authenticated) проверяется, и Перенаправление на / home вызывается.Но каким-то образом ваш маршрутизатор снова перенаправляется на / .Компонент App перерисовывается.Условие if(this.props.authenticated) снова выполняется, и маршруты снова направляются в приложение. Создает бесконечный цикл , поэтому вы видите сообщение Превышена максимальная глубина обновления .

В index.js , для целей тестирования замените все PrivateRoute на Route , чтобы проверить правильность работы маршрута.Если это работает, проблема может быть связана с компонентом PrivateRoute .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...