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

When using stickyHeaderIndices and the title of the 1st header changes, the displayed title is not updated #615

Open
xavi opened this issue Sep 26, 2022 · 8 comments
Labels
bug Something isn't working

Comments

@xavi
Copy link

xavi commented Sep 26, 2022

Current behavior

Using version 1.2.2 on iOS as a SectionList. If stickyHeaderIndices is not used, everything is fine, but if used...

when the 1st section has only 1 item, and the title of the section is changed, the displayed title is not updated. In order to see the correct updated title, it's necessary to force its re-display (ex. by scrolling down, which causes the title to be hidden, and then scrolling up so that it's displayed again).

Expected behavior

I would expect the title of the 1st section to be immediately updated, as it happens with other sections, and even with the 1st one when stickyHeaderIndices is not used.

To Reproduce

Platform:

  • iOS

Environment

1.2.2

@xavi xavi added the bug Something isn't working label Sep 26, 2022
@IvanIhnatsiuk
Copy link

IvanIhnatsiuk commented Oct 20, 2022

I can confirm this issue. it just doesn't unmount and stays "on top" of the next one header. You can generally see it in the second video, when the header has a colour and overlap the next one.

First video

Screen.Recording.2022-10-20.at.21.47.59.mov

Second video

Screen.Recording.2022-10-20.at.21.53.12.mov
import React, {useState} from 'react';
import type {Node} from 'react';
import {Button, StyleSheet, View, Text, SafeAreaView} from 'react-native';
import {FlashList} from '@shopify/flash-list';

const renderItem = ({item}) =>
  typeof item === 'string' ? (
    <View style={styles.sectionContainer}>
      <Text style={{color: 'green', fontSize: 14}}>sticky header {item}</Text>
    </View>
  ) : (
    <View style={styles.itemContainer}>
      <Text style={{color: 'red', fontSize: 14}}>{item.title}</Text>
    </View>
  );

const data1 = new Array(500)
  .fill(0)
  .map((_, index) =>
    index % 20 === 0
      ? `first-data-sticky-${index}`
      : {title: `first-data-item-${index}`},
  );
const data2 = new Array(500)
  .fill(0)
  .map((item, index) =>
    index % 20 === 0
      ? `second-data-sticky-${index}`
      : {title: `second-data-item-${index}`},
  );

const App: () => Node = () => {
  const [data, setData] = useState(data1);

  const stickyHeaderIndices = data
    .map((item, index) => (typeof item === 'string' ? index : null))
    .filter(item => item !== null);

  return (
    <SafeAreaView style={{flex: 1}}>
      <Button onPress={() => setData(data1)} title="set first data" />
      <Button onPress={() => setData(data2)} title="set second data" />
      <View style={{flex: 1, backgroundColor: 'white'}}>
        <FlashList
          renderItem={renderItem}
          estimatedItemSize={55}
          stickyHeaderIndices={stickyHeaderIndices}
          keyExtractor={item => (typeof item === 'string' ? item : item.title)}
          data={data}
        />
      </View>
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  sectionContainer: {
    paddingVertical: 8,
    paddingHorizontal: 24,
    borderBottomWidth: 1,
    backgroundColor: 'red',
  },
  itemContainer: {
    padding: 24,
  },
});

export default App;

@gerwim
Copy link

gerwim commented Nov 20, 2022

Can confirm this issue is also present in 1.4.0.

mergify bot pushed a commit to desmos-labs/dpm that referenced this issue Jan 26, 2023
## Description

Closes: #XXXX



This PR fixes the transactions section header not updating correctly.  
Unfortunally the bug is casued from this issue (Shopify/flash-list#615 ) of the `FlashList` library.

---

### Author Checklist

*All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.*

- [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [x] provided a link to the relevant issue or specification
- [x] reviewed "Files changed" and left comments if necessary
- [x] confirmed all CI checks have passed

### Reviewers Checklist

*All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.*

- [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] confirmed all author checklist items have been addressed
RiccardoM pushed a commit to desmos-labs/dpm that referenced this issue Jan 30, 2023
## Description

Closes: #XXXX



This PR fixes the transactions section header not updating correctly.  
Unfortunally the bug is casued from this issue (Shopify/flash-list#615 ) of the `FlashList` library.

---

### Author Checklist

*All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.*

- [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [x] provided a link to the relevant issue or specification
- [x] reviewed "Files changed" and left comments if necessary
- [x] confirmed all CI checks have passed

### Reviewers Checklist

*All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.*

- [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] confirmed all author checklist items have been addressed
@jcloquell
Copy link

We ended up switching back to React Native's FlatList because of this issue, as it is not happening there, and in the screen where we had this issue, performance was not a problem.

But I was able to create a (hacky) hook that successfully fixes the issue with FlashList. It relies on a couple of states to unset and reset the sticky headers and trigger the component to re-render, and that way, the view of the sticked header gets updated:

const useUpdateStickyHeaders = (data: string[]) => {
  const [stickyHeadersUpdate, triggerStickyHeadersUpdate] = useState<boolean>(false);
  const [, triggerRerender] = useState<boolean>(false);

  const stickyHeaderIndices = useRef<number[] | undefined>(undefined);
  const actualStickyHeaderIndices = useRef<number[] | undefined>(undefined);

  actualStickyHeaderIndices.current = data
    .map((item, index) => (item === "header" ? index : -1)) // Map the data in the way you need to extract the headers' indices
    .filter(index => index !== -1);

  useEffect(() => {
    stickyHeaderIndices.current = actualStickyHeaderIndices.current;
    triggerRerender(value => !value);
  }, [stickyHeadersUpdate, triggerRerender]);

  const updateStickyHeaders = useCallback(() => {
    stickyHeaderIndices.current = undefined;
    triggerStickyHeadersUpdate(value => !value);
  }, [triggerStickyHeadersUpdate]);

  // UNCOMMENT THIS BLOCK IF YOUR DATA IS LOADED ASYNCHRONOUSLY, OTHERWISE IT WILL FAIL TO STICK THE FIRST HEADER INITIALLY
  // const hasSetStickyHeadersInitially = useRef<boolean>(false);
  // useEffect(() => {
  //   if ((actualStickyHeaderIndices.current?.length ?? 0) > 0 && !hasSetStickyHeadersInitially.current) {
  //     hasSetStickyHeadersInitially.current = true;
  //     stickyHeaderIndices.current = actualStickyHeaderIndices.current;
  //     triggerRerender(value => !value);
  //   }
  // }, [data, triggerRerender]);

  return {
    updateStickyHeaders,
    stickyHeaderIndices: stickyHeaderIndices.current,
  };
};

You just need to modify the data that the hook receives, and the way the data is mapped to extract the sticky headers' indices, matching your use case.

The hook returns the stickyHeaderIndices which should be directly passed as a prop to the FlashList component, and a function updateStickyHeaders() which should be called right after your data/headers have been updated.

Hope this is useful for someone running into this issue 🙂

@jongbelegen
Copy link

Another temp fix I found for my use case is to rerender the Flashlist component if the first item is a header and changes.

Btw i experienced this error in react native web (with expo)

<FlashList
        key={
          typeof items[0] === "string" ? activeClients[0] : undefined
        }

Any insights into fixing this in the codebase would be appreciated though!

@jianxinzhoutiti
Copy link

+1

1 similar comment
@L-Weisz
Copy link

L-Weisz commented Nov 6, 2024

+1

@L-Weisz
Copy link

L-Weisz commented Nov 6, 2024

this is still an issue, I created a snackbox to replicate the bug https://snack.expo.dev/@healico/flashlist-as-section-list-bug

@virendrasingh-tech
Copy link

virendrasingh-tech commented Nov 18, 2024

+1, also not able to change view styles and other property, i think it is memoized.

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

8 participants