I have an issue where I will send a user to a react-router route after login, based on the following:
...
//check login
browserHistory.push(self.props.destination_url);
I was expecting componentDidMount
to run, since this component had not been on the screen since I loaded the app, but it will not. If I click a link to it (react-router link) in the nav bar, componentDidMount
does run however.
I just need to make an API call when this component comes on the screen because of a browserHistory.push(self.props.destination_url);
route change. I've tried things like
<Router createElement={ (component, props) =>
{
const { location } = props
const key = `${location.pathname}${location.search}`
props = { ...props, key }
return React.createElement(component, props)
} }/>
here Component does not remount when route parameters change and it isn't working.
Here http://busypeoples.github.io/post/react-component-lifecycle/ shows "on mount", "on unmount", "on state change", or "on props changes". I'm not seeing any of those apply here. Is there a lifecycle method that will run after this browserHistory push transition?
I've been trying random lifecycle methods and componentWillUpdate
does run after browserHistory.push
but it runs hundreds of times, completely slowing the app down. I'd assume something I did inside it caused the nearly infinite loop:
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);
});
}
}
On the server/client you now see the POST run hundreds of times:
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;
...
This will work for the student's demo, but not longterm. Looking for a lifecycle method that will only run once, and that changing state is safe and won't cause infinite loop
My r
dependencies look like
"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",
These routes are looking like
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);
})
What is the purpose of push() and replace() methods of history ? A history instance has two methods for navigation purpose. If you think of the history as an array of visited locations, push() will add a new location to the array and replace() will replace the current location in the array with the new one.
React Router uses the history package, which builds on the browser history API to provide an interface to which we can use easily in React apps. location - (object) The current location. May have the following properties: pathname - (string) The path of the URL.
history. push is updating url but not re rendering : r/reactjs.
Using history.push() is another approach where we make use of the history props React Router provides while rendering a component. In other words, this works when the component is being rendered by React Router, bypassing the component as a Component prop to a Route.
don't put API calls in a component lifecycle.
create an action
function getUserInfo(payload) {
// do axios
return {
type: 'GET_USER_INFO',
payload: result_of_your_api_call,
error: false/true
};
}
create reducer for this action and mutate state in reducer
after that, you need to matStateToProps and mapDispatchToProps
connect(mapStateToProps, mapDispatchToProps)(YourMagicComponent)
that connects your component and your redux
After that, you get a redux state in your component. For more information please read this http://redux.js.org/docs/basics/ExampleTodoList.html
Remember 1. when component initialized it hasn't any data in props except defaultProps. 2. componentDidMount doesn't know anything outside component (available only default props and props defined before component mounted) 3. if you need to do something in componentWillUpdate you need to define rules for update that's component
componentWillUpdate(nextProps) {
this.setState(key: nextProps.key)
}
shouldComponentUpdate(nextProps, nextState) {
// fix for your update
if (this.state.key !== nextProps.key) {
return true;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With