David Schilling
David Schilling

Reputation: 2758

React/Redux Lazy load data

I have a React application which uses Redux as state container.

I have a REST API which I use to load data into the app. Some of the data only contains IDs and to show the real content behind the IDs I need to fetch more data from the REST API.

To make an example:

I fetch a list of events. These events have speakers and participants. When I click on an event in the app it shows the speaker and also some of the participants, but it's only a preview of them. So not all of them are shown. To show a person, with its image and a name, I need to make another API call.

My question is what is the best way to structure my code so I just need to call the API for the persons that are shown. So if I click on one event I only need to load the persons involved in this event, and also only the ones that are previewed.

I also try to have my components which render the persons not depend on the Redux store but be just plain React components which get their state from their props.

I can provide more details if needed.

Upvotes: 3

Views: 4089

Answers (1)

Marco van Dijk
Marco van Dijk

Reputation: 244

You can simply load your extra data using componentDidMount make the API call and set the state locally or dispatch an async Action Creator in the componentDidMount, store the event in your redux store and retrieve it. Depends if you want to use the event detail data in other parts of your application or it is only used in that particular view, and what your personal preference is of course.

Using local state ->

class EventDetail extends React.Component {

    constructor() {
        super(props);

        this.state = {
            event: null
        };
    }

    componentDidMount() {

        // Get event id from passed prop
        const id = this.props.eventId;

        // Or using react-router, so you can directly link to the URL 
        // https://reacttraining.com/react-router/web/example/url-params
        const id = this.props.match.params.eventId;

        // Make API call using whatever you are using
        // HTTP GET 'events/${id}' -> Details including persons

        apiCallToGetEventDetailsIncludingPersons(id)
            .then(event => { this.setState({ event: event }); })
            .catch(err => { /* handle error */ } );
    }

    render() {

        // Render result when data is set
        // Possible to show loader when data is not yet retrieved instead of null value

        return this.state.event ? (
            <div>Your view</div>
        ) : null;
    }
}

Using Redux ->

class EventDetail extends React.Component {

    constructor() {
        super(props);
    }

    componentDidMount() {

        // Get event id from passed prop
        const id = this.props.eventId;

        // Or using react-router, so you can directly link to the URL 
        // https://reacttraining.com/react-router/web/example/url-params
        const id = this.props.match.params.eventId;

        // Fire async action creator
        this.props.getEvent(id);
    }

    render() {

        // Render result when data is set
        // Possible to show loader when data is not yet retrieved instead of null value

        return this.props.event ? (
            <div>Your view</div>
        ) : null;
    }
}

const mapStateToProps = (state) => ({
    event: state.yourReducer.whatYouNameYourStoredEvent
});

const mapDispatchToProps = (dispatch) => ({
    getEvent: (id) => dispatch(getAsyncEventDetailsAction(id))
});

const EventDetailContainer = connect(mapStateToProps, mapDispatchToProps)(EventDetail);

Upvotes: 2

Related Questions