Skip to content

Commit c73cc10

Browse files
committed
📝 Significantly update the README
Emphasize VirtualizedList over ListView.
1 parent cfdb602 commit c73cc10

File tree

1 file changed

+109
-127
lines changed

1 file changed

+109
-127
lines changed

README.md

+109-127
Original file line numberDiff line numberDiff line change
@@ -11,38 +11,44 @@
1111

1212
<br>
1313

14-
A drop-in replacement for React Native's [`ListView`](https://facebook.github.io/react-native/docs/listview.html).
15-
16-
:sparkles: NEW! It also supports the new `VirtualizedList` component (the underlying component used by `FlatList`) as of `v0.3.0`;
17-
see the [instructions at the bottom](#immutablevirtualizedlist) for more details and version requirements.
14+
A drop-in replacement for React Native's [`ListView`](https://facebook.github.io/react-native/docs/listview.html),
15+
[`FlatList`](https://facebook.github.io/react-native/docs/flatlist.html),
16+
and [`VirtualizedList`](https://facebook.github.io/react-native/docs/virtualizedlist.html).
1817

1918
![ImmutableListView screenshot](example/screenshots/listview-cropped.png "ImmutableListView screenshot")
2019

21-
It supports [Immutable](https://facebook.github.io/immutable-js/) data out-of-the-box to give you
22-
faster performance and less headaches.
20+
It supports [Immutable.js](https://facebook.github.io/immutable-js/) to give you faster performance and less headaches.
2321

2422
## Motivation
2523

26-
- Do you find yourself re-implementing `rowHasChanged` and setting `dataSource` over and over?
27-
- Do you use Immutable data, only to write wrappers for data access in order to use them with a ListView?
28-
- Do you listen for lifecycle events simply so you can update `dataSource` -- and thus you can't easily use pure functional components with lists?
24+
- Do you use Immutable data, only to write the same boilerplate over and over in order to display it?
25+
- Do you want to show 'Loading...', 'No results', and 'Error!' states in your lists?
2926
- Do you have nested objects in your state so a shallow diff won't cut it for pure rendering?
30-
- Do you show 'Loading...', 'Empty', and 'Error!' states in your lists?
31-
- Do you use a navigator and want better performance while animating?
27+
- Do you want better performance while animating screen transitions?
3228

33-
If you answered yes to ANY of these questions, this project will surely help.
34-
Check out the [examples](https://github.com/cooperka/react-native-immutable-list-view#how-to-format-your-data) below!
29+
If you answered yes to ANY of these questions, this project can help. Check out the examples below.
3530

3631
## How it works
3732

33+
For FlatList and VirtualizedList:
34+
35+
```jsx
36+
<ImmutableVirtualizedList
37+
immutableData={this.state.listData}
38+
renderItem={this.renderItem}
39+
/>
40+
```
41+
42+
For ListView:
43+
3844
```jsx
3945
<ImmutableListView
4046
immutableData={this.state.listData}
4147
renderRow={this.renderRow}
4248
/>
4349
```
4450

45-
The screenshot above shows two different lists. The first simply uses this data:
51+
The screenshot above shows two different lists. The first uses this data:
4652

4753
```js
4854
Immutable.fromJS({
@@ -63,12 +69,6 @@ The second list is even simpler:
6369
Immutable.Range(1, 100)
6470
```
6571

66-
It supports all the props of React Native's [`ListView`](https://facebook.github.io/react-native/docs/listview.html#props),
67-
but instead of passing in a `dataSource`, you pass in a prop called `immutableData`.
68-
69-
This prop is just the raw data you'd like to display -- `ImmutableListView` will handle creating an efficient `dataSource` for you.
70-
Other than this small change, everything else will be exactly the same as `ListView`.
71-
7272
There's an example app [here](https://github.com/cooperka/react-native-immutable-list-view/tree/master/example)
7373
if you'd like to see it in action.
7474

@@ -80,19 +80,68 @@ if you'd like to see it in action.
8080

8181
2. Import it in your JS:
8282

83+
For FlatList and VirtualizedList:
84+
85+
```js
86+
import { ImmutableVirtualizedList } from 'react-native-immutable-list-view';
87+
```
88+
89+
For ListView:
90+
8391
```js
8492
import { ImmutableListView } from 'react-native-immutable-list-view';
8593
```
8694

87-
## Example Usage
95+
## Example usage -- replacing FlatList
96+
97+
Goodbye, `keyExtractor` boilerplate!
98+
99+
> Note: This example diff looks much better on [GitHub](https://github.com/cooperka/react-native-immutable-list-view#example-usage----replacing-flatlist) than on npm's site.
100+
> Red means delete, green means add.
101+
102+
```diff
103+
-import { Text, View, FlatList } from 'react-native';
104+
+import { Text, View } from 'react-native';
105+
+import { ImmutableVirtualizedList } from 'react-native-immutable-list-view';
106+
107+
import style from './styles';
108+
import listData from './listData';
109+
110+
class App extends Component {
111+
112+
renderItem({ item, index }) {
113+
return <Text style={style.row}>{item}</Text>;
114+
}
115+
116+
render() {
117+
return (
118+
<View style={style.container}>
119+
<Text style={style.welcome}>
120+
Welcome to React Native!
121+
</Text>
122+
- <FlatList
123+
- data={listData}
124+
- getItem={(items, index) => items.get(index)}
125+
- getItemCount={(items) => items.size}
126+
- keyExtractor={(item, index) => String(index)}
127+
+ <ImmutableVirtualizedList
128+
+ immutableData={listData}
129+
renderItem={this.renderItem}
130+
/>
131+
</View>
132+
);
133+
}
134+
135+
}
136+
```
137+
138+
## Example usage -- replacing ListView
88139

89140
You can remove all that boilerplate in your constructor, as well as lifecycle methods like
90141
`componentWillReceiveProps` if all they're doing is updating your `dataSource`.
91142
`ImmutableListView` will handle all of this for you.
92143

93-
Check out this example diff:
94-
95-
> Note: This looks much better on [GitHub](https://github.com/cooperka/react-native-immutable-list-view#example-usage) than on npm's site.
144+
> Note: This example diff looks much better on [GitHub](https://github.com/cooperka/react-native-immutable-list-view#example-usage----replacing-listview) than on npm's site.
96145
> Red means delete, green means add.
97146

98147
```diff
@@ -156,29 +205,34 @@ Check out this example diff:
156205

157206
## Customization
158207

159-
All the props supported by React Native's `ListView` are simply passed through, and should work exactly the same.
160-
You can read about them [here](https://facebook.github.io/react-native/docs/listview.html#props).
208+
All the props supported by React Native's underlying List are simply passed through, and should work exactly the same.
209+
You can see all the [VirtualizedList props](https://facebook.github.io/react-native/docs/virtualizedlist.html#props)
210+
or [ListView props](https://facebook.github.io/react-native/docs/listview.html#props) on React Native's website.
161211

162-
You can fully customize the look of your list by implementing [`renderRow`](https://facebook.github.io/react-native/docs/listview.html#renderrow)
163-
and, optionally, [`renderSectionHeader`](https://facebook.github.io/react-native/docs/listview.html#rendersectionheader).
212+
You can customize the look of your list by implementing [`renderItem`](https://facebook.github.io/react-native/docs/flatlist.html#renderitem) for FlatList and VirtualizedList
213+
or [`renderRow`](https://facebook.github.io/react-native/docs/listview.html#renderrow) for ListView.
164214

165-
Here are the additional props that `ImmutableListView` accepts:
215+
Here are the additional props that `ImmutableVirtualizedList` and `ImmutableListView` accept:
166216

167217
| Prop name | Data type | Default value? | Description |
168218
|-----------|-----------|----------------|-------------|
169219
| `immutableData` | Any [`Immutable.Iterable`](https://facebook.github.io/immutable-js/docs/#/Iterable/isIterable) | Required. | The data to render. See below for some examples. |
170220
| `rowsDuringInteraction` | `number` | `undefined` | How many rows of data to initially display while waiting for interactions to finish (e.g. Navigation animations). |
171221
| `sectionHeaderHasChanged` | `func` | `(prevSectionData, nextSectionData) => false` | Only needed if your section header is dependent on your row data (uncommon; see [`ListViewDataSource`'s constructor](https://facebook.github.io/react-native/docs/listviewdatasource.html#constructor) for details). |
172-
| `renderEmpty` | `string` or `func` | `undefined` | If your data is empty (e.g. `null`, `[]`, `{}`) and this prop is defined, then this will be rendered instead. Pull-refresh and scrolling functionality will be **lost**. |
173-
| `renderEmptyInList` | `string` or `func` | `'No data.'` | If your data is empty (e.g. `null`, `[]`, `{}`) and this prop is defined, then this will be rendered instead (inside of an [`EmptyListView`](#emptylistview)). Pull-refresh and scrolling functionality will be **kept**! |
222+
| `renderEmpty` | `string` or `func` | `undefined` | If your data is empty (e.g. `null`, `[]`, `{}`) and this prop is defined, then this will be rendered instead. Pull-refresh and scrolling functionality will be **lost**. Most of the time you should use `renderEmptyInList` instead. |
223+
| `renderEmptyInList` | `string` or `func` | `'No data.'` | If your data is empty (e.g. `null`, `[]`, `{}`) and this prop is defined, then this will be rendered instead. Pull-refresh and scrolling functionality will be **kept**! See [below](#loading--empty--error-states) for more details. |
224+
225+
Also see [React Native's `FlatListExample`](https://github.com/facebook/react-native/blob/master/RNTester/js/FlatListExample.js)
226+
for more inspiration.
174227

175228
## Methods
176229

177-
Methods such as `scrollTo` and `scrollToEnd` are passed through just like the props described above.
178-
You can read about them [here](https://facebook.github.io/react-native/docs/listview.html#methods).
230+
Methods such as `scrollToEnd` are passed through just like the props described above.
231+
You can read about them [here](https://facebook.github.io/react-native/docs/listview.html#methods) for ListView
232+
or [here](https://facebook.github.io/react-native/docs/virtualizedlist.html#methods) for FlatList and VirtualizedList.
179233

180-
The references to `ListView` and `VirtualizedList` are available via `getListView()` and `getVirtualizedList()`.
181-
These references allow you to access any other methods on the List component that you might need.
234+
The references to the raw `VirtualizedList` or `ListView` component are available via `getVirtualizedList()` or `getListView()`.
235+
These references allow you to access any other methods on the underlying List that you might need.
182236

183237
## How to format your data
184238

@@ -219,102 +273,30 @@ for list data. Here are some examples:
219273

220274
To try it out yourself, you can use the [example app](https://github.com/cooperka/react-native-immutable-list-view/tree/master/example)!
221275

222-
## Differences from ListView
223-
224-
When using section headers, `ImmutableListView` treats certain types of `Immutable.Map` slightly differently
225-
than `ListView` treats an equivalent plain JS `Map`. See the snapshot test output
226-
[here](https://github.com/cooperka/react-native-immutable-list-view/blob/master/src/__tests__/__snapshots__/ImmutableListView.test.js.snap)
227-
for an example of how `ImmutableListView` behaves, or try it for yourself.
228-
229-
It seems based on the [current documentation](https://facebook.github.io/react-native/releases/0.37/docs/listviewdatasource.html#constructor)
230-
that **`ImmutableListView` is behaving as expected**, and in fact regular `ListView` is the one being weird.
231-
In any case, you should make sure to test this behavior yourself if you're using a `Map` with section headers.
232-
233-
Other than this, the two should behave identically. You can verify this with the unit tests
234-
[here](https://github.com/cooperka/react-native-immutable-list-view/blob/master/src/__tests__/comparison.test.js).
235-
236-
## EmptyListView
237-
238-
This component takes an optional `emptyText` prop and renders an `ImmutableListView` with only a single list item with the text you specified.
239-
By default, this string is simply `'No data.'`.
240-
241-
Example:
242-
243-
```jsx
244-
import { ImmutableListView, EmptyListView } from 'react-native-immutable-list-view';
245-
246-
<ImmutableListView
247-
immutableData={this.state.listData}
248-
renderRow={this.renderRow}
249-
renderEmpty={() => <EmptyListView emptyText="Nothing to see here!" />}
250-
/>
251-
```
276+
Support is coming soon for section headers with `ImmutableVirtualizedList` too, similar to [`SectionList`](https://facebook.github.io/react-native/docs/sectionlist.html).
277+
See [PR #34](https://github.com/cooperka/react-native-immutable-list-view/pull/34).
252278

253-
If you need more flexibility, instead of passing `emptyText` to `EmptyListView`, you can pass `renderRow` and display anything you want.
254-
`EmptyListView` will pass all your props through to `ImmutableListView` (and then through to `ListView`).
279+
## Loading / Empty / Error states
255280

256-
If you want to handle something like pull-refresh while empty, you can use the `originalProps`, e.g.:
281+
The optional `renderEmptyInList` prop takes a string and renders an Immutable List displaying the text you specified.
282+
By default, this text is simply `No data.`, but you can customize this based on your state. For example:
257283

258284
```jsx
259-
<ImmutableListView
260-
...
261-
refreshControl={<RefreshControl ... />}
262-
renderEmpty={(originalProps) =>
263-
<EmptyListView
264-
refreshControl={originalProps.refreshControl}
265-
emptyText="Nothing to see here!"
285+
render() {
286+
const emptyText = this.state.isLoading
287+
? "Loading..."
288+
: this.state.errorMsg
289+
? "Error!"
290+
: "No data.";
291+
292+
return (
293+
<ImmutableVirtualizedList
294+
immutableData={this.state.listData}
295+
renderItem={this.renderItem}
296+
renderEmptyInList={emptyText}
266297
/>
267-
}
268-
/>
269-
```
270-
271-
## ImmutableVirtualizedList
272-
273-
Just as the `ImmutableListView` component helps render a `ListView` using Immutable data,
274-
`ImmutableVirtualizedList` helps render the new and improved `VirtualizedList` component.
275-
This is the underlying component that `FlatList` uses.
276-
277-
There's a [Medium article about it](https://medium.com/@cooperka/react-native-new-flatlist-component-30db558c7a5b) if you'd like more context.
278-
The short version of the setup instructions is below:
279-
280-
#### With React Native v0.43 or higher
281-
282-
1. Make sure you're using at least `v0.5` of this library
283-
2. Import the component:
284-
285-
```js
286-
import { ImmutableVirtualizedList } from 'react-native-immutable-list-view';
287-
```
288-
289-
#### With React Native v0.42 or lower
290-
291-
1. Make sure you're using `v0.4.x` of this library
292-
2. Download the required files into your app's `node_modules` (since these components aren't published in a release quite yet):
293-
294-
https://gist.github.com/cooperka/c5dd3ab11f588044d4d6ba22d52c4ab0
295-
296-
or, using the [shell script](https://github.com/cooperka/react-native-immutable-list-view/blob/v0.4.5/bin/download-flatlist.sh) from this library:
297-
298-
```bash
299-
npm run download-flatlist
300-
```
301-
302-
3. Import the component directly:
303-
304-
```js
305-
import ImmutableVirtualizedList from 'react-native-immutable-list-view/lib/ImmutableVirtualizedList';
306-
```
307-
308-
#### All React Native versions
309-
310-
After following the above steps, simply render it:
311-
312-
```jsx
313-
<ImmutableVirtualizedList
314-
immutableData={this.state.listData}
315-
renderItem={this.renderItem}
316-
/>
298+
);
299+
}
317300
```
318301

319-
See the [example app](https://github.com/cooperka/react-native-immutable-list-view/tree/master/example) for a working demo,
320-
or [React Native's `FlatListExample`](https://github.com/facebook/react-native/blob/master/RNTester/js/FlatListExample.js) for an idea of what features are possible.
302+
The empty list will receive all the same props as your normal list, so things like pull-to-refresh will still work.

0 commit comments

Comments
 (0)