2017-09-28 1 views
6

J'ai un problème où je vais envoyer un utilisateur à un routeur réagir itinéraire après la connexion, en fonction de ce qui suit: J'étaiscomponentDidMount ne fonctionne pas après avoir appelé browserHistory.push («/url »)

 ... 
     //check login 
     browserHistory.push(self.props.destination_url); 

attendre componentDidMount pour exécuter, puisque ce composant n'avait pas été sur l'écran depuis que j'ai chargé l'application, mais il ne sera pas. Si je clique sur un lien vers celui-ci (lien reacteur-routeur) dans la barre de navigation, componentDidMount fonctionne cependant.

J'ai juste besoin de faire un appel d'API quand ce composant arrive à l'écran à cause d'un changement d'itinéraire browserHistory.push(self.props.destination_url);. J'ai essayé des choses comme

<Router createElement={ (component, props) => 
{ 
    const { location } = props 
    const key = `${location.pathname}${location.search}` 
    props = { ...props, key } 
    return React.createElement(component, props) 
} }/> 

ici Component does not remount when route parameters change et il ne fonctionne pas.

Ici http://busypeoples.github.io/post/react-component-lifecycle/ montre "sur montage", "sur démontage", "sur changement d'état", ou "sur les changements d'accessoires". Je ne vois aucun de ceux qui s'appliquent ici. Existe-t-il une méthode de cycle de vie qui s'exécutera après cette transition de navigateurHistory? Merci

J'ai essayé des méthodes de cycle de vie aléatoires et componentWillUpdate fonctionne après browserHistory.push mais il fonctionne des centaines de fois, ralentissant complètement l'application. Je suppose que je l'ai fait à l'intérieur a provoqué la boucle presque infinie:

componentWillUpdate() { 
    console.log('it ran componentWillUpdate'); 
    if (this.props.email) { 

     console.log('firing off /api/userInfo'); 
     let self = this; 
     axios.post('/api/userInfo', {email: this.props.email}) 
      .then(function (response) { 
       let result = response.data.result; 
       console.log('after calling /api/userInfo'); 
       console.log(response); 
       console.log(result); 
       if (result) { 
        self.setState({restaurant_profile: result}); 
       } 
      }) 
      .catch(function (error) { 
       console.log("Something went wrong trying to check for a user's restaurant profile"); 
       console.log(error); 
      }); 
    } 
} 

Sur le serveur/client que vous voyez maintenant le POST exécuter des centaines de fois:

Executing (default): SELECT `id`, `email`, `password`, `RestaurantId` FROM `Users` AS `User` WHERE `User`.`email` = '[email protected]' LIMIT 1; 

Executing (default): SELECT `id`, `email`, `password`, `RestaurantId` FROM `Users` AS `User` WHERE `User`.`email` = '[email protected]' LIMIT 1; 

Executing (default): SELECT `id`, `email`, `password`, `RestaurantId` FROM `Users` AS `User` WHERE `User`.`email` = '[email protected]' LIMIT 1; 

Executing (default): SELECT `id`, `email`, `password`, `RestaurantId` FROM `Users` AS `User` WHERE `User`.`email` = '[email protected]' LIMIT 1; 

... 

Cela fonctionne pour l'étudiant de démo, mais pas à long terme. La recherche d'une méthode de cycle de vie qui ne fonctionnera une fois, et que l'état changeant est sûr et ne provoque pas la boucle infinie

Mes r dépendances ressemblent

"react": "^15.6.1", 
"react-dom": "^15.6.1", 
"react-redux": "^5.0.6", 
"react-router": "^3.0.5", 
"react-router-dom": "^4.2.2", 
"react-transform-hmr": "^1.0.4", 
"redux": "^3.7.2", 

Ces itinéraires sont à la recherche comme

import React from "react"; 
import ReactDOM from "react-dom"; 
import { Provider } from "react-redux"; 
import { createStore, applyMiddleware } from "redux"; 
import { Router, Route, Link, IndexRoute, browserHistory } from "react-router"; 

import reducers from "./reducers"; 
import { loadConfig, getConfig } from "./config"; 
import Nav from "./Nav"; 
import LoginPage from "./containers/LoginPage"; 
import MapShowRestaurants from "./components/MapShowRestaurants"; 
import RestaurantRegistration from "./containers/RestaurantRegistration"; 


const createStoreWithMiddleware = applyMiddleware()(createStore); 


getConfig.then((config) => { 
    loadConfig(config); 

    ReactDOM.render(
     (
      <Provider store={createStoreWithMiddleware(reducers)}> 
       <Router history={browserHistory}> 
        <Route path="/" component={Nav}> 
         <IndexRoute component={MapShowRestaurants} /> 
         <Route path="/login" component={LoginPage} /> 
         <Route path="/registerRestaurant" component={RestaurantRegistration} /> 
        </Route> 
       </Router> 
      </Provider> 
     ), document.querySelector('.container')); 
}) 
.catch((err) => { 
    console.log(err); 
}) 

Merci

+0

I sachez que componentDidMount n'est appelé qu'une fois, ce qui explique pourquoi il ne fonctionne pas comme prévu (parce que (je crois) react-router fait un rendu initial avant d'être appelé). Je peux me tromper - d'où le commentaire et non une réponse. Je vais voir si je ne peux pas trouver les docs pour ça. De plus, comme vous l'avez découvert, componentWillUpdate() n'est pas le bon endroit pour cela ... vous pourriez essayer de créer votre propre méthode, puis l'appeler dans le callback de browserPush? Juste une pensée. – archae0pteryx

+0

Comment l'appeler dans 'browserHistory.push'? D'après ce que je comprends vous venez de passer l'URL que vous voulez aller et il le pousse dans l'histoire et vous redirige là – codyc4321

+0

Je pensais que vous pourriez ajouter un rappel ... lorsque vous cherchez cette information, j'ai trouvé ceci: https: // github.com/ReactTraining/react-router/issues/3554 – archae0pteryx

Répondre

3

ne pas mettre les appels d'API dans le cycle de vie d'un composant.

créer une action

function getUserInfo(payload) { 
    // do axios 
    return { 
     type: 'GET_USER_INFO', 
     payload: result_of_your_api_call, 
     error: false/true 
    }; 
} 

créer réducteur pour cette action et de l'état muter réducteur

après cela, vous devez matStateToProps et mapDispatchToProps

connect(mapStateToProps, mapDispatchToProps)(YourMagicComponent) 

qui relie le composant et redux

Après cela, vous obtenez un re l'état dux dans votre composant. Pour plus d'informations s'il vous plaît lire ceci http://redux.js.org/docs/basics/ExampleTodoList.html

Rappelez-vous 1.Lorsque le composant est initialisé, il n'a aucune donnée dans les accessoires sauf defaultProps. 2. componentDidMount ne sait rien en dehors de composant (disponible uniquement des accessoires par défaut et accessoires définis avant le composant monté) 3. Si vous avez besoin de faire quelque chose componentWillUpdate vous devez définir des règles pour la mise à jour qui est le composant

componentWillUpdate(nextProps) { 
    this.setState(key: nextProps.key) 
} 

shouldComponentUpdate(nextProps, nextState) { 
    // fix for your update 
    if (this.state.key !== nextProps.key) { 
    return true; 
    } 
} 
+0

J'ai un test pour un travail, je vais rouvrir la prime quand je peux vérifier ces – codyc4321

2

@ codyc4321 essayer self.props.router.push ('/ url')

+0

Pouvez-vous ajouter un peu de contexte à votre réponse? Pourquoi cela devrait-il fonctionner? Quelle est l'erreur qu'elle fixe par rapport à ce que le PO a essayé. – dubes

+0

J'ai un test pour un travail, je vais rouvrir la prime quand je peux vérifier ces – codyc4321