Reputation: 287
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
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 Table
component 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 tracks
array 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
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