Skip to content
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

First sticky header is not updated when data is changed #814

Open
2 tasks done
todorone opened this issue Apr 14, 2023 · 25 comments
Open
2 tasks done

First sticky header is not updated when data is changed #814

todorone opened this issue Apr 14, 2023 · 25 comments
Labels
bug Something isn't working

Comments

@todorone
Copy link

todorone commented Apr 14, 2023

Current behavior

When we update data of list with sticky headers, the first one(that is currently sticky) is not updated, while the rest is updated.

Expected behavior

Items are updated when data is changed

To Reproduce

https://snack.expo.dev/@todorone/flashlist-sticky-headers-bug

  • We have 2 header items A and D.
  • Pressing "SWAP"
  • Headers items should be B and C, instead we see A and C
  • When scrolled up/down, items are rendered correctly and we see B and C

Platform:

  • iOS
  • Android

Environment

1.3.1

@todorone todorone added the bug Something isn't working label Apr 14, 2023
@radko93
Copy link

radko93 commented May 4, 2023

We can reproduce the same behaviour.

@j-duggirala
Copy link

Any work around to fix this issue?

@todorone
Copy link
Author

@naqvitalha any chance to provide at least temporary workaround?

@MaxFedak
Copy link

have same issue.

P.S.: If you add an element to array (even if it's not rendered), and add his index to sticky headers, it will update your first sticky header.

@LinusU
Copy link

LinusU commented Sep 1, 2023

This still happens in version 1.4.3

I've currently worked around it by updating the key prop every time we change the headers. Unfortunately this causes the list to briefly flash as the entire list is re-rendered...

@BuqiLiao
Copy link

BuqiLiao commented Sep 5, 2023

A better way to fix this rather than updating the key prop to cause flashing is to add a fake header and increase the stickyHeaderIndices:

  const renderItem = ({ item }) => {
    if(item === "FAKE_HEADER") return null;
    if (typeof item === "string") {
      return <MyChatSectionHeader title={item} />;
    }
      return <MyChatItem
        item={item}
        navigation={navigation}
      />
    };
  const stickyHeaderIndices = myChats
    .map((item, index) => (typeof item === "string" ? index+1 : null))
    .filter(index => index !== null);

  <FlashList
    data={["FAKE_HEADER", ...myChats]}
    renderItem={renderItem}
    keyExtractor={item => typeof item === "string" ? item : item._id}
    onEndReached={loadMoreChatsHandler}
    onEndReachedThreshold={0.05}
    ListFooterComponent={<LoadingMoreFooter isLoadingMore={isLoadingMore} />}
    stickyHeaderIndices={stickyHeaderIndices}
    getItemType={item => typeof item === "string" ? "sectionHeader" : "row"}
    estimatedItemSize={70}
  />

However, there will be a slight shake if you scroll up the list since the fake header's indices is counted

@BuqiLiao
Copy link

BuqiLiao commented Sep 5, 2023

I just found a ever better solution without even slight shaking:
Try to increase the indices once and immediately change back to origin:

  const [stickyIndices, setStickyIndices] = useState([]);
  useEffect(() => {
    const getStickyIndices = (number=0) => {
      return myChats
      .map((item, index) => (typeof item === "string" ? index+number : null))
      .filter(index => index !== null);
    }
    setStickyIndices(getStickyIndices(1));
    setTimeout(() => {
      setStickyIndices(getStickyIndices(0));
    }, 100);
  }, [myChats.length]);
  <FlashList
    data={myChats}
    renderItem={renderItem}
    keyExtractor={item => typeof item === "string" ? item : item._id}
    onEndReached={loadMoreChatsHandler}
    onEndReachedThreshold={0.05}
    ListFooterComponent={<LoadingMoreFooter isLoadingMore={isLoadingMore} />}
    stickyHeaderIndices={stickyIndices}
    getItemType={item => typeof item === "string" ? "sectionHeader" : "row"}
    estimatedItemSize={70}
  />

After all, those are temporary solutions, hope someone could make a PR for this

@itajenglish
Copy link

+1

1 similar comment
@Himanshu0230
Copy link

+1

@bryanltobing
Copy link

this issue is still exist

@domenvilar
Copy link

I have the same problem. First sticky header is not updated when the data changes.

@dpatterson414
Copy link

+1

2 similar comments
@MoeKanan
Copy link

+1

@pmj100
Copy link

pmj100 commented Nov 28, 2023

+1

@switz
Copy link

switz commented Dec 19, 2023

Yeah, honestly seeing a lot of bugs tied directly to stickyHeaderIndices unfortunately

@MikeKovarik
Copy link

+1

1 similar comment
@victorlucss
Copy link

+1

@GollyJer
Copy link

GollyJer commented Mar 30, 2024

I can't believe how much time I wasted before finding this bug report. 🥲
Thanks for the workaround @BuqiLiao

@jianxinzhoutiti
Copy link

+1

@pehagg
Copy link

pehagg commented May 30, 2024

As a simpler workaround, use Array for the sticky headers, e.g.

  const stickyHeaderIndices = new Array(...);

This will force the FlashList to detect the change. No need for useState hooks or setTimeOut.

edit: posted this solution a little too prematurely. This will re-render the first item, but the item is no longer sticky. Sigh.
edit2: this seems to work after all, I had a bug in my code that didn't set the first item as a sticky header

MateWW added a commit to MateWW/flash-list that referenced this issue Jul 10, 2024
MateWW added a commit to MateWW/flash-list that referenced this issue Jul 10, 2024
MateWW added a commit to MateWW/flash-list that referenced this issue Jul 10, 2024
MateWW added a commit to MateWW/flash-list that referenced this issue Jul 13, 2024
@GollyJer
Copy link

Does this have an official fix in the works?

@DominicWrege
Copy link

Any updates on that ? 🥺

@DTupalov
Copy link

DTupalov commented Sep 2, 2024

What is the status of this issue? I see that the PR is ready. When do you plan to release it?

naqvitalha pushed a commit that referenced this issue Sep 12, 2024
@charlie-nis
Copy link

charlie-nis commented Oct 6, 2024

@pehagg

As a simpler workaround, use Array for the sticky headers, e.g.

const stickyHeaderIndices = new Array(...);
This will force the FlashList to detect the change. No need for useState hooks or setTimeOut.

edit: posted this solution a little too prematurely. This will re-render the first item, but the item is no longer sticky. Sigh. edit2: this seems to work after all, I had a bug in my code that didn't set the first item as a sticky header

your solution works beautifully

 const stickyIndices: number[] = new Array(
    ...resultsItems
      .map((item, index) => {
        if (typeof item === "string") {
          return index;
        } else {
          return null;
        }
      })
      .filter((item) => item !== null)
  );

@DTupalov
Copy link

DTupalov commented Oct 8, 2024

I see that PR #1267 has been merged into the main branch, and that’s awesome! :)
When do you plan to release this fix?

Thanks for the response.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests