-
Notifications
You must be signed in to change notification settings - Fork 24.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[ListView] prepend function ? #1682
Comments
Can you post the code that you're using with this? Are you using |
My bad, I should have said prepend instead of append. since its something to do with the history of messages, I first remove an item if it exists and then unshift it so that its at the top. Here's a small snippet var chatMessages = main.state.chatMessages; //this is the code I am not too fond of, and would like it to be simpler INSIDE MY _RENDERROWS function this.setState({dataSource: this.state.dataSource.cloneWithRows( |
I'm having a similar issue. Trying to dynamically add items the beginning of my ListView, but when I call setState to update the DataSource, it doesn't work correctly. I do get a new row added (to the end), but it's just a duplicate of the last item. Before insertion: Then, after inserting [D] at the beginning of my DataSource array I get: If I explicitly return |
had the same issue: |
I'm seeing the same issue, but @akabab 's concat approach doesn't work in my case. |
Any news about this? I've spent the best part of my day trying to simply unshift a new item at the top of my ListView without success. I'm having the exact same issue than @marcshilling ... PS: @marcshilling , can you explain what you mean by "If I explicitly return true from rowHasChanged"? |
When defining the ListView dataSource, literally just doing this: dataSource: new ListView.DataSource({
rowHasChanged: (row1, row2) => {
//return row1 !== row2;
return true;
}
}) |
I just ran across this same issue and switching from |
After playing around with this a bit, it seems that because ListView assigns keys based on row index, anytime the datasource is prepended to, it will re-render all rows. This can be fixed by assigning a row specific key to the StaticRenderer on line 346 of ListView and also setting shouldUpdate={false}. Obviously this is not a generic solution for react-native core, but it is trivial to copy your own "StaticListView" with these two line changes to prevent row rerender. Also I do not yet have it working with sticky headers. Perhaps I am missing something, but it appears ListView's were not designed to prepend without rerender. It would be great to get this supported, but it would require a signifigant change to the way the data source works. |
Actually sticky headers work no problem: https://gist.github.com/rt2zz/d1298e7b860e0707d7b4 Note for anyone trying to use this component, it is not well though out, and may break under certain prop combination or with unorthodox datasource setups. Also the row data must have a unique id property, as this is used as the row component key. |
Ok so, I think I figured out what's going on with my particular issue. The key was closing my data first so you get a brand new object reference, and then making my changes. I'm using the lodash library to accomplish this with the function let newData = _.cloneDeep(this.state.data);
newData.unshift({name: 'Marc Shilling', avatarUrl: null});
this.setState({
data: newData
}); My new row is now successfully being added to the top of the ListView. Maybe you guys already knew this, but hopefully I'll help someone else. Still doesn't solve the issue of causing the entire list to be re-rendered though, since with the addition of the new row obviously everything is shifted by 1. |
Any news on this? Is there a way to prepend a row without re-rendering the whole list? This seems like a really buggy behavior |
Here are the requirements for prepending without an entire re-render:
|
@brentvatne @ide by looking at ListViewDataSource, it looks like datasource assigns keys based on row index
meaning that any time an item gets pretended a whole re-rerender is triggered. The Edit |
According to the best answer here: Just need 2 steps:
"it tries to compare the new data rows with the existing rows (if any) in the dataSource, and figures out whether there are new rows to insert, or existing rows that need to be replaced or removed." |
What is wrong with the answer of @marcshilling ? seems to be exactly what we need to prepend data |
I thought I'd comment on this as it's confused me quite a few times in the past.. Using cloneDeep to achieve this is not really a good solution, it's quite an expensive and unnecessary operation if you have an array of nested objects and breaks the reference equality check ide mentioned. This basically makes rowHasChanged equate to true but is actually even less performant than doing I've been playing around with this myself, at first I was under the impression that using a combination of unshift and specifying
|
@kyle-ssg could you share more info about your config, I'm trying to prepend to the data source and your key fix isn't working for me |
See Here. This example highlights 2 cases, 1 where you use keys and another where you don't. You can take this example and pass |
Thanks! Was this written recently? I'm on react-native 0.40.0 and its not working for me |
Example is using "react-native": "0.40.0", you can just run the app on the repo. |
I would like to append stuff on a ListView, and stay on the original position
My rowHasChanged is r1.message != r2.message
Currently I unshift the new data to be appended. I have noticed sometimes it doesnt update the ListView, and I have had to tinker with the dirtyRows to force an update.
Can anyone help me achieve what I intend to ?
The text was updated successfully, but these errors were encountered: