Proper Way To Structure Immutable.js Data When Passing To React Components As Props

- 1 answer

In a react web app with a flux architecture I'm trying to use Immutable.js to store the data to take advantage of fast shouldComponentUpdate comparisons.

I have a store that holds an Immutable map of messages and then a channel component that displays all the messages associated with the channel. Let's say I set the state like this:

this.state.messages = MessageStore.getMessages()
    .filter(message => { message.channelId === currentChannelId});

Then I render the channel like this:

<Channel messages={this.state.messages}/>

The channel won't be able to do a fast comparison without checking every message because the filter function always returns a new object as far as I understand.

Is it possible for filter to return the same underlying object on each call if the messages didn't change?

Or should I just restructure my data so that in the MessageStore messages are stored in separate maps for each channel. That way I could just have:

this.state.messages = MessageStore.getMessages(currentChannelId);

And behind the scenes it would just be returning the specific map that wouldn't change until a new message was added.

Alternatively does it make more sense to just pass all messages to the channel component and it would perform the filtering inside itself?

I'm leaning towards changing how the data is structured in the store but was wondering if I'm missing something with how the filter function works.



Within the Channel component, you will again be distributing the messages across several children Message components. The re-render cost gets distributed across each child component in turn. If they are also "pure", then it hardly matters that the Channel component's render is invoked again. Only the truly changed messages will render again, as within the new iterator returned by filter, the underlying message objects will still be the same unless they have changed.

However, if you still want to avoid the render, you can either remodel the data to store messages in a channel specific map, or within your store, you can cache the filter iterator and keep returning the same in every getMessages call. And in the actions which mutate message, change the cached reference to a new value. This way if messages haven't changed, you will always get the same iterator.