stack_pooper
stack_pooper

Reputation: 287

Structuring my React/Redux app for efficiency

Im building an audio workstation app that will display a table of tracks containing clips. Right now I have a table reducer which returns a table object. The table object contains track objects and the track objects contain clip objects. I have a TableContainer which subscribes to the table store. My issue is I believe my app will be inefficient because it will re render the page every time a clip is added or manipulated. In reality only the particular track in which the clip resides would need to be re rendered right? How can I structure my app so not every little change re renders the entire app?

Upvotes: 2

Views: 78

Answers (2)

DDS
DDS

Reputation: 4375

In the mapStateToProps of any component, don't select parent objects as a whole to send to the component. If possible select specific properties all the way to the leaf values. If your TableContainer's render() itself doesn't use the tracks array them make sure only the sibling properties that you do use get passed.

So instead of:

function mapStateToProps(state, props) {
  return {
    table: state.tables[props.tableId];
  }
}

Do:

function mapStateToProps(state, props) {
  let table = state.tables[props.tableId];
  return {
    name: table.name, 
    type: table.type
  };

This allows React Redux to be more discerning when it comes to determining whether your component needs to be rerendered. It will see that even though the table had changed due to a clip change, neither the name, nor the type has changed.

However, since your Tablecomponent likely renders the Track components as well, you're likely not going to be able to avoid render calls. If any property anywhere up the tree gets altered, the tracks array also gets altered.

The solution in this case is to have the tracksarray not contain the entire track object but instead only a list of track IDs. You can then store the tracks alongside the tables and a change in one won't affect the other. Note that this only works if you do not go and fetch and pass the track object in the mapStateToProps of the Table component. You should make theTrack component in such a way that it accepts its ID instead of the actual object as a prop. This way the Table component is not dependent on the contents of the tracks at all.

Upvotes: 2

Christopher Chiche
Christopher Chiche

Reputation: 15325

The power of react is to re-render only what needs to be (by using the virtual DOM to make the comparison and the shouldComponentUpdate function).

I wouldn't look too much into it before it becomes a performance problem.

If it does, I would store the tracks in a separate directory and don't pass it to the app (main) component. In your Clip component's mapStateToProps function (if you use react-redux), fetch the track from the state as you get it's name from the props. This way if the track changes a lot (because of async fetching of slices for example), only the component will update.

Upvotes: 1

Related Questions