Reputation: 177
I'm creating a react web application using react-router to navigate between the pages. Some of these pages depend on componentDidMount running when you navigate to the page. However, it seems this doesn't run unless I refresh the page which seems very counter-intuitive to users.
Is there a way to force componentDidMount to run when the render method completes perhaps.
Sorry if this is seen as a duplicate question but nothing I've seen has helped me understand how to solve this issue.
componentDidMount = async () => {
//initialize web3
const web3 = await getWeb3();
// get contract address
const ethAddress = await storehash.options.address
this.setState({ethAddress})
//set account for Blockchain network
this.setState({account: await web3.eth.getAccounts()})
}
Upvotes: 3
Views: 3630
Reputation: 101
You can use the componentDidUpdate
lifecycle method to compare previous props
with current props
and rerun the logic again; like
constructor(props) {
super(props);
this.componentLogic = this.componentLogic.bind(this);
}
componentLogic() {
// fetch something or some other business logic
}
componentDidMount() {
this.componentLogic();
}
componentDidUpdate(prevProps) {
// Typical usage (don't forget to compare props):
if (
this.props.reactRouterDom.params.slug !==
prevProps.reactRouterDom.params.slug
) {
this.componentLogic();
}
}
Here I am passing route slug as prop via Higher Order Component(HOC)
, and tracking change in route via componentDidUpdate
lifecycle.
Upvotes: 1
Reputation: 1397
tl;dr - Only Components rendered by Route (and their children) will re-render on a route change.
I'm going to make a few assumptions. One is that the componentDidMount
you're trying to use is on a component that is not a child of one of your Route components.
The second assumption I'll make is that you don't need to run when that component mounts, but when one of the new routes' components mounts.
The componentDidMount
function in the Component that's being rendered by the Route is probably where you need to be. However, if you need to update something in this component's state when one of its children mounts, that won't help. However you can go about this a couple different ways.
Quick and Dirty Don't get in the habit of doing this
If you're just testing something, a quick and dirty method is to use a route's render
property instead of component
.
So for example, if your route looks like this:
<Route path="/some-route" component={NewComponent} />
You could change this (again... only for a quick test, not recommended to have this in any production code!)
<Route path="/some-route" render={(props) => {
//do your console log or temporary testing stuff here
return <NewComponent ...props />
}} />
Pass down a function, that will pass up vars from the child
A less dirty way, and assuming you want the code to have access to something on this parent component, would be to pass down a function to the component. Again, you'd have to use render
for this:
someFunction = (passedVar) => {
// do something with passedVar, which you'll pass from the new component
}
// ... then in the Router...
<Route path="/some-route" render={(props) => <NewComponent ...props onRouteLoaded={this.someFunction} />}} />
Then you'd have a function (this.props.onRouteLoaded(...)
) that you can run on the componentDidMount
of the NewComponent
- NOT on this parent component. This will allow you to pass vars up to the parent component if you need to access that component's state, props etc.
Recommended if you need to do that
A much cleaner way to do it, would be to use Redux state to pass values around, but (completely respectfully) get your head around React lifecycles before you breach Redux (but you SHOULD breach Redux!)
Upvotes: 2