react-native-draggable-flatlist icon indicating copy to clipboard operation
react-native-draggable-flatlist copied to clipboard

Draggable Flatlist random behavior

Open njoshi94 opened this issue 4 years ago • 1 comments

I am currently using a draggable flatlist in react-navigation and am working on resetting the screen each time the screen has loaded (both with navigation, and going back). I am resetting the screen using a listener in useEffect() I have an array stored in props, and a local array that is the data for the draggable flatlist. The user can rearrange the flatlist to update the local array and then can hit "update" to update the array in props. My issue is, if I rearrange the flatlist, then switch screens and come back, the flatlist will be displayed in the correct order, but random things will happen when I click on the last item. Sometimes items will disappear, sometimes items will move together, instead of separately, sometimes the last item will randomly jump to a different spot, and sometimes the whole thing will error out.

I didn't have this error before adding the useEffect and am unsure where the best place to debug is.

Props array: data = [ { key: 0, name: 'Value 1', }, { key: 1, name: 'Value 2', }, { key: 2, name: 'Value 3, }, { key: 3, name: 'Value 4', } ];

Screen:

export default function Screen1(props, {navigation}) {   

  useEffect(() => { 
    const unsubscribe = props.navigation.addListener('focus', () => {
      setLocalData(props.Data)
    });
    return unsubscribe;
  }, [navigation]);

const [localData, setLocalData] = useState([])

const renderItem = ({ item, index, drag, isActive }) => {  
    return (
      <TouchableOpacity
        style={{
          backgroundColor: isActive ? "#516EE1" : '#93A5B4',
          alignItems: "center",
          justifyContent: "center",
          marginBottom: 1.5,
          marginLeft: 30,
          marginRight: 30,
          paddingLeft: 16,
          height: 28,
          borderColor: "black",
          borderWidth: 2,
          borderRadius: 5
        }}
        onPressIn={drag}>
        <Text
          style={styles.buttonTitle}
        > 
        {item.name} 
        </Text>
      </TouchableOpacity>
    );
  };

return (
    <SafeAreaView style={styles.container}>
        <SafeAreaView              >
             <DraggableFlatList
                data = {localData}
                renderItem={renderItem}
                keyExtractor={(item, index) => `draggable-item-${item.key}`}
                onDragEnd={({ data }) => {
                    setLocalData(data);
                }}
            /> 
            <TouchableOpacity
                style={styles.button}
                onPress={() => onUpdatePress()}>
                <Text style={styles.buttonTitle}>Update</Text>
            </TouchableOpacity>
            <SafeAreaView style={styles.footerView}>
                <Text onPress = {() => {
                  props.navigation.navigate('Next Screen')
                  }} style={styles.footerLink}>Skip </Text>
            </SafeAreaView>
          </SafeAreaView>
    </SafeAreaView>
)
}

njoshi94 avatar Dec 30 '20 17:12 njoshi94

not sure about the weird list behavior, but a few things i noticed:

  • you should probably pull addListener off of navigation and use that as your effect dep, or wrap navigation in a ref-- it changes often and that effect likely runs a lot.
  • renderItem should be wrapped in a useCallback

computerjazz avatar Jan 22 '21 04:01 computerjazz