2017-09-28 2 views
6

Ich habe ein Problem, wo ich einen Benutzer zu einer Reaktion-Router Route nach der Anmeldung senden werde, basierend auf den folgenden:componentDidMount nicht aktiv nach browserHistory.push Aufruf („/ url“)

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

Ich war erwartet componentDidMount zu laufen, da diese Komponente nicht auf dem Bildschirm war, seit ich die App geladen habe, aber es wird nicht. Wenn ich in der Navigationsleiste auf einen Link (react-router link) klicke, läuft componentDidMount jedoch.

Ich brauche nur einen API-Aufruf, wenn diese Komponente auf dem Bildschirm wegen einer browserHistory.push(self.props.destination_url); Route Änderung kommt. Ich habe Dinge versucht, wie

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

hier Component does not remount when route parameters change und es funktioniert nicht.

Hier zeigt http://busypeoples.github.io/post/react-component-lifecycle/ "on mount", "bei Unmount", "bei Statusänderung" oder "bei Requisitenänderungen". Ich sehe keine von denen hier zutreffen. Gibt es eine Lifecycle-Methode, die nach dem browserHistory Push-Übergang ausgeführt wird? Danke

Ich habe zufällige Lifecycle-Methoden versucht und componentWillUpdate funktioniert nach browserHistory.push, aber es läuft Hunderte von Mal, die App vollständig verlangsamt. Ich würde davon ausgehen, etwas, was ich tat seinem Inneren die fast unendliche Schleife verursacht:

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); 
      }); 
    } 
} 

Auf dem Server/Client sehen Sie jetzt die POST laufen mehrere hundert Mal: ​​

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; 

... 

Dies wird für die Schüler arbeiten Demo, aber nicht langfristig. Sie suchen einen Lifecycle-Methode, die nur einmal ausgeführt wird, und dass eine Änderung Zustand ist sicher und wird nicht Endlosschleife

Meine r Abhängigkeiten wie

aussehen verursachen
"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", 

Diese Routen suchen wie

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); 
}) 

Danke

+0

I weiß, dass componentDidMount nur einmal aufgerufen wird, weshalb es nicht so funktioniert, wie du es erwartest (weil (glaube ich) react-router eine initiale render, bevor es tatsächlich aufgerufen wird) könnte ich falsch liegen - daher der kommentar und keine antwort. Ich werde sehen, ob ich die Dokumente dafür nicht finden kann. Wie Sie festgestellt haben, ist componentWillUpdate() auch dafür nicht geeignet ... Sie könnten versuchen, eine eigene Methode zu erstellen und sie dann im browserPush-Callback aufzurufen. Nur ein Gedanke. – archae0pteryx

+0

Wie würde ich es in 'browserHistory.push' nennen? Von dem, was ich verstehe, übergeben Sie es einfach die URL, die Sie gehen möchten, und es drängt es in den Verlauf und leitet Sie dorthin – codyc4321

+0

Ich dachte, Sie könnten einen Rückruf hinzufügen ... bei der Suche nach dieser Info fand ich das: https: // github.com/ReactTraining/react-router/issues/3554 – archae0pteryx

Antwort

3

setzen Sie keine API-Aufrufe in einen Komponentenlebenszyklus.

schaffen eine Aktion

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

Minderer für diese Aktion erstellen und

danach Zustand in Minderer mutieren, müssen Sie matStateToProps und mapDispatchToProps

connect(mapStateToProps, mapDispatchToProps)(YourMagicComponent) 

, die Ihre Komponente verbindet und Ihre redux

Danach erhalten Sie eine Re dux Zustand in Ihrer Komponente. Für weitere Informationen lesen Sie bitte diese http://redux.js.org/docs/basics/ExampleTodoList.html

Denken Sie daran, 1.Wenn die Komponente initialisiert wurde, enthält sie keine Daten in Requisiten außer defaultProps. 2. componentDidMount weiß nichts außerhalb Komponente (definiert nur Standard Requisiten und Requisiten vor Komponente montiert) 3. wenn Sie etwas in componentWillUpdate tun müssen, was Sie brauchen für Fortschreibungsregeln zu definieren, die Komponente ist

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

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

überprüfen kann Ich habe einen Test für einen Job, ich werde Bounty wieder öffnen, wenn ich diese überprüfen kann – codyc4321

2

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

+0

Kannst du bitte etwas Kontext zu deiner Antwort hinzufügen? Warum sollte das funktionieren? Was ist der Fehler, den es im Vergleich zu dem hat, was das OP versucht hat? – dubes

+0

Ich habe einen Test für einen Job, ich werde Bounty wieder öffnen, wenn ich diese – codyc4321

Verwandte Themen