3

I'm using react, alt.js, and react-router, and building an application with basic CRUD. There is a menu item for "Create Item", and it brings up a modal (using react-bootstrap...) and on submit it fires an action to create some model on the backend, and then does a browserHistory.push (as recommended in react-router docs) when that completes go to the item page for the newly created item.

So in the basic case, this works. For example if I'm on the main app page it works. However, if I was already on the item detail page for a different item (let's say I was on /item/1 and I just created /item/2, so I'm trying to redirect to /item/2 from page /item/1).

And my async load logic (well, the action call at least, for fetchItem) is in componentDidMount of the ItemViewPage react component, which seems pretty typical based on all the examples I can find online.

And the problem is, if the page was currently already rendered, componentDidMount never gets called, because the component is already mounted(!). And so my page URL updates to /item/2, but the contents are still for /item/1.

So, my question is....Yeah. Am I wrong to initiate data load from componentDidMount? Am I supposed to do it some other lifecycle method (say, componentWillReceiveProps, since the react router will set a new id)? Or is there some other place entirely where I should be firing off data load from (e.g. does react-router have some feature I'm not aware of that handles this)?

6
  • ShouldComponentUpdate is my guess, but it's probably best if you post some code. Commented Jun 30, 2016 at 21:36
  • it would be a lot of code, probably! But anyway just typing out the question led me to try componentWillReceiveProps, and I test there for if (this.props.params.id !== newProps.params.id) { this.props.fetchItem(newProps.params.id); }, which seems to work. It makes sense I guess, but it caught me by surprise that it doesn't work out of the box. Commented Jun 30, 2016 at 21:39
  • How would it work "out of the box" without knowing your params? Anyways, glad you got it working. Perhaps next time, do more research before posting a question ;) Commented Jun 30, 2016 at 21:48
  • componentDidMount is only fired when the component is mount the first time. So componentWillReceiveProps is effectively the right way to go here. Commented Jun 30, 2016 at 21:52
  • 1
    Most examples online don't mention this. And it's a little weird (at least I think) that you have to duplicate your load logic in two different life cycle methods. Commented Jun 30, 2016 at 21:56

1 Answer 1

2

Since React is smart and knows that you re-use the component for your route, the component will remain mounted. The lifecycle method of your choice will not be able to handle the job, since it gets called on the initial mounting of the component, once.

I would advise you to use componentWillReceiveProps and in there you can check if, let's say, the id field of your item changed. That means you should probably update since there's new, different data to render.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.