Package Exports
- react-native-immutable-list-view
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (react-native-immutable-list-view) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
React Native Immutable ListView
A drop-in replacement for React Native's ListView.

It supports Immutable data out-of-the-box to give you faster performance and less headaches.
Code
<ImmutableListView
immutableData={this.state.listData}
renderRow={this.renderRow}
/>The screenshot above shows two different lists. The first simply uses this data:
Immutable.fromJS({
'Section A': [
'foo',
'bar',
],
'Section B': [
'fizz',
'buzz',
],
})The second list is even simpler:
Immutable.Range(1, 100)Motivation
- Do you find yourself re-implementing
rowHasChangedand savingdataSourceto your state over and over? - Do you use Immutable data, only to write wrappers for data access in order to use them with a ListView?
- Do you listen for lifecycle events simply so you can update
dataSource-- and thus you can't easily use pure functional components with lists? - Do you have nested objects in your state so a shallow diff won't cut it for pure rendering?
- Do you use a navigator and want better performance while animating?
If you answered yes to ANY of these questions, this project will surely help. Check out the examples below!
Usage
Install:
Import it in your JS:
import ImmutableListView from 'react-native-immutable-list-view';
It supports all the props of React Native's ListView,
but instead of passing in a dataSource, you should should pass in a prop called immutableData.
This prop is just the raw data you'd like to display -- ImmutableListView will handle creating an efficient dataSource for you.
Other than this small change, everything else will be exactly the same as ListView.
There's an example app here if you'd like to see it in action.
Example Usage
You can remove all that boilerplate in your constructor, as well as lifecycle methods like
componentWillReceiveProps if all they're doing is updating your dataSource.
ImmutableListView will handle all of this for you.
Check out this example diff:
Note: This looks much better on GitHub than on npm's site. Red means delete, green means add.
-import { Text, View, ListView } from 'react-native';
+import { Text, View } from 'react-native';
+import ImmutableListView from 'react-native-immutable-list-view';
import style from './styles';
import listData from './listData';
class App extends Component {
- constructor(props) {
- super(props);
-
- const dataSource = new ListView.DataSource({
- rowHasChanged: (r1, r2) => r1 !== r2,
- sectionHeaderHasChanged: (s1, s2) => s1 !== s2,
- });
-
- const mutableData = listData.toJS();
-
- this.state = {
- dataSource: dataSource.cloneWithRowsAndSections(mutableData),
- };
- }
-
- componentWillReceiveProps(newProps) {
- this.setState({
- dataSource: this.state.dataSource.cloneWithRows(newProps.listData),
- });
- }
-
renderRow(rowData) {
return <Text style={style.row}>{rowData}</Text>;
}
renderSectionHeader(sectionData, category) {
return <Text style={style.header}>{category}</Text>;
}
render() {
return (
<View style={style.container}>
<Text style={style.welcome}>
Welcome to React Native!
</Text>
- <ListView
- dataSource={this.state.dataSource}
+ <ImmutableListView
+ immutableData={listData}
renderRow={this.renderRow}
renderSectionHeader={this.renderSectionHeader}
/>
</View>
);
}
}Props
All the props supported by React Native's ListView are simply passed through, and should work exactly the same.
You can read about them here.
You can fully customize the look of your list by implementing renderRow
and, optionally, renderSectionHeader.
Here are the additional props that ImmutableListView accepts:
| Prop name | Data type | Default value? | Description |
|---|---|---|---|
immutableData |
Any Immutable.Iterable |
Required. | The data to render. See below for some examples. |
rowsDuringInteraction |
number |
undefined |
How many rows of data to initially display while waiting for interactions to finish (e.g. Navigation animations). |
sectionHeaderHasChanged |
func |
(prevSectionData, nextSectionData) => false |
Return true if your section header is dependent on your row data (uncommon; see ListViewDataSource's constructor for more info). |
How to format your data
ImmutableListView accepts several standard formats
for list data. Here are some examples:
List
[rowData1, rowData2, ...]Map of Lists
{
section1: [
rowData1,
rowData2,
...
],
...
}Map of Maps
{
section1: {
rowId1: rowData1,
rowId2: rowData2,
...
},
...
}To try it out yourself, you can use the example app!
Differences from ListView
When using section headers, ImmutableListView treats certain types of Immutable.Map slightly differently
than ListView treats an equivalent plain JS Map. See the snapshot test output
here
for an example of how ImmutableListView behaves, or try it for yourself.
It seems based on the current documentation
that ImmutableListView is behaving as expected, and in fact regular ListView is the one being weird.
In any case, you should make sure to test this behavior yourself if you're using a Map with section headers.
Other than this, the two should behave identically. You can verify this with the unit tests here.