Describe the bug
On the initial render of the component rowMap passed to renderHiddenItem and renderItem is an empty object. It almost seems that rowMap is async value and gets resolved afterwards.
If I try to log and inspect it in console it shows as:


But after new data is passed to component (it fetches new data every N seconds), the rowMap is the expected object:

Here is a little snippet of the component:
<SwipeListView
style={styles.container}
keyExtractor={item => item.System_Notifications_ID.toString()}
data={searchActive ? data : data.filter(i => !i.hidden
&& i.System_Notifications_Status !== statusTypes.DISMISSED)}
renderItem={renderItem}
renderHiddenItem={({ item }, rowMap) => {
console.log(rowMap);
const row = rowMap[item.System_Notifications_ID.toString()];
const closeAction = row && row.closeRow.bind(row);
const newActions = actions.map((actionObj) => {
const newItem = { ...actionObj };
newItem.action = _.isFunction(actionObj.action)
? newItem.action.bind(null, item)
: closeAction;
return newItem;
});
return <HiddenItem actions={newActions} actionsStyle={actionsStyle} />;
}}
rightOpenValue={-width}
disableRightSwipe
/>
I debugged it a bit and it appears that ref={row => (this._rows[key] = row) method of <SwipeRow/> is called after renderHiddenItem and renderItem, since they are called here:
renderItem(rowData, rowMap) {
const Component = this.props.renderItem(rowData, rowMap);
const HiddenComponent =
this.props.renderHiddenItem &&
this.props.renderHiddenItem(rowData, rowMap);
const { item, index } = rowData;
let { key } = item;
if (!key && this.props.keyExtractor) {
key = this.props.keyExtractor(item, index);
}
const shouldPreviewRow =
typeof key !== 'undefined' && this.props.previewRowKey === key;
return this.renderCell(
Component,
HiddenComponent,
key,
item,
shouldPreviewRow
);
}
so rowMap is not filled at the time of first render of items
Closing the issue as I found a solution. In case anyone runs in the problem. Don't create bound functions at the time of rendering (hidden)items. I added a function to my component:
const closeRow = (key, map) => map[key] && map[key].closeRow();
and changed renderHiddenItem to:
renderHiddenItem={({ item }, rowMap) => {
const closeAction = () => closeRow(item.System_Notifications_ID, rowMap);
const newActions = actions.map((actionObj) => {
const newItem = { ...actionObj };
newItem.action = _.isFunction(actionObj.action)
? newItem.action.bind(null, item)
: closeAction;
return newItem;
});
return <HiddenItem actions={newActions} actionsStyle={actionsStyle} />;
}}
Worked for me ! Thanks.
For some reason the keys in my rowMap are like 1-undefined, but eh, whatever, this still works.
Edit: The undefined was here because my keyExtractor functions was bad
Most helpful comment
Closing the issue as I found a solution. In case anyone runs in the problem. Don't create bound functions at the time of rendering (hidden)items. I added a function to my component:
and changed renderHiddenItem to: