In the two React applications I’m actively expanding and maintaining many of the entities follow a steady set of state transitions. An entity starts in the unloaded state. When a container needs more than just the ID of the entity then container dispatches an action to request the loading. There is generally little to no user interface value beyond knowing the entity is in the process of being loaded. Once the entity concludes loading into the browser, then the component begins using the data structure.

This is fine and dandy for a single entity. Load times are general low and you have three states of a single entity. Then we get to collections of entities. Small collections generally don’t produce very many problems. However once one gets beyond a relatively low order, about 20 items, you begin flooding your reducers with actions. Many APIs will allow one to request multiple entities at a single time, or maybe for performance reasons you should batch all the reduce actions.

Today I got the bright idea the container component should be the one dispatching a command for bulk loading. This would alleviate flooding Redux state changes. I’m probably missing something here, but I figured I would dig in and see if it would be helpful. Effectively the approach would be to aggregate the IDs to be loaded from the contained components, then at a signal the sub-components have completed their the container should dispatch a bulk load request.

For initial loading, the componentDidMount() method looks appropriate. For updates, the componentDidUpdate(prevProps, prevState, snapshot) should fit the bill. Just a quick sketch:


import React from 'react';

class Container extends React.Component {
	
	loadEntity( id ){
		this.load_entities = (this.load_entities || []);
		this.load_entities.append(id)
	}
	
	render() {
		return (
			<div>
			    { this.props.entities.map( (entity) => {
			    	return (<EntityView entity={entity} key={entity.id} load={() => { this.loadEntity(entity.id) }/>);
			    })}
			</div>
		);
	}
	
	_doBulkLoad() {
        const load = this.load_entities || [];
        if( load.length > 0 ){
            this.load_entities = [];
            this.props.bulkLoadEntities( load );
        }
	}
	
	componentDidMount() {
        this._doBulkLoad();
	}
	
	componentDidUpdate() {
        this._doBulkLoad();
	}
}

class EntityView extends React.Component {
    componentDidMount() {
        if( shouldLoad( this.props.entity )){
        	this.props.load();
        }
    }

	render() {
		return (<div>{this.props.entity.message}</div>);
	}
}

This is of course a simplified version, and completely untested. There are cases where it probably makes more sense to wait to load (progress page loading, etc). Hopefully this paradigm will reduce the action storm.