0

Im doing React app with Redux and React-Router

For example i have 6 million profile pages

/id1
/id2
...
/id6000000

and they all should be draw by ProfilePage component. so i just doing something like:

class ProfilePage extends Component {
    componentDidMount() {
        httpApi.getProfileData(this.props.match.params.id)
        .then(response => {
            this.setState({
                page: response
            })
        })
    }

    ...
}

Its works great.

But next i want to use Redux for the same things (i will call dispatch directly for easy reading).

Also we need to understand that we not need page data in global store, except as for use connected props in underlying components(we can easly replace it by createContext). We just use Redux to move logic and request in outer space.

class ProfilePage extends Component {
    static propTypes = {
        page: propTypes.object // from connect
    }

    componentDidMount() {
        dispatch({type: 'PROFILEPAGE_LOADING_START', id: this.props.match.params.id});
    }

    ...
}

which after middle-ware call a reducer and set store:

PROFILEPAGE_LOADING_SUCCESS:
    return {
        profilePage: action.page
    }

So i think now everything works fine, except one thing.

For example we stay at profile page with id1 and going to id3, our react-router unmount profilePage[id1] and mount profilePage[id3], and its render with old[id1] data before new data is loaded, because we not remove old data from store. Hmm.

I understand we can implement a page keys or loading state or clear state at componentDidMount (but it still render with old data before mounting) something else, but it is a bit ugly and have side effects.

Question: What the best practice?

And second, if i want to implement prefetch data loading at link click before history push. Its very easy to implement without Redux, just use history push state and use this state in componentDidMount.

But if I use Redux then its ABSOLUTELY TERRIBLE thing. For first i need to resolve first question by any ugly way, and second i need to join together somehow data change in store and render by react router. Otherwise need to implement shouldComponentUpdate logic, which is ugly too and not trigger in some cases.

I tried a lot of solutions and they work but all ugly as hell.

Question 2: What the solution?

3
  • Are you checking to see if the new props coming form redux is different from the old props? Commented Jun 5, 2019 at 15:44
  • Can you expand for what and where? i tried to check props in different concepts. For page key, location or existence of data. But they all have exceptions which require even more ugly code Commented Jun 5, 2019 at 16:07
  • I mean when the id changes, the component gets updated, you can try to use componentDidUpdate() simpler Api to shouldComponentUpdate. then compare the previous props with the new props, and only re-render the component when it's a new prop Commented Jun 5, 2019 at 16:13

1 Answer 1

1
  1. On PROFILEPAGE_LOADING_START in reducer you can set profilePage to undefined. IMHOit's the simplest and easiest way.
  2. You can dispatch action PROFILEPAGE_LOADING_START before push and in ProfilePage just show the profilePage if it's not undefined or loading indicator if undefined.
Sign up to request clarification or add additional context in comments.

4 Comments

1. its looks like good solution pobably its work, i not tried yet because mainly did prefetch data load routing.
But i not understand second answer:( We not have any loading indicator, we just replace one page by another instantly as data loaded together with history push. So main problem there in lifecycles and react-router triggers. In one or another way it did wrong render. Mainly because we have different ways to load page, by cold load, reload, default link or custom prefetch link. And can have only one source of truth. Yes i did it with SCU and some checks but it looks soo cumbersome, i not want use it) I had something like this: pastebin.com/R52W4mH7
@moetsy loading indicator is optional. You can just show empty page or page without data instead. It's up to you.
Anyway if I understand it right, you says just to split location push and data change, but it leads to a lot of prop check like in my previos pastebin example, maybe somewhere exists a better example idk. For example to prefech loading with just state is one string and i looking for same simple redux solution: pastebin.com/UpiHRyR5

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.