gitim / react-native-sortable-list

React Native Sortable List component
MIT License
884 stars 279 forks source link

List view blinks when updating the data #143

Open sangeethkumarv opened 5 years ago

sangeethkumarv commented 5 years ago

I have implemented the sortable list, I have background API running using a timer every 20 seconds. when every API updates the list content, sortable listview blinks before rendering the new list item.

And also I have blink issue after sorting the list also because I am updating the order sequence to the server using API.

Note: I have implemented redux for state management. Please let me know if anybody else is facing the same problem.

Akash-T2S commented 5 years ago

Even i'm facing the same problem @sangeethkumarv. Kindly find the below code.

App.js

import React, {Component} from 'react'; import { Animated, Easing, StyleSheet, Text, Image, View, Dimensions, Platform, TouchableOpacity } from 'react-native'; import SortableList from 'react-native-sortable-list'; import {SwipeRow} from 'react-native-swipe-list-view';

const window = Dimensions.get('window');

export default class Basic extends Component {

state = {
    data : {
        0: {
            image: 'https://placekitten.com/200/240',
            text: 'heya',
        },
        1: {
            image: 'https://placekitten.com/200/201',
            text: 'Jasper',
        },
        2: {
            image: 'https://placekitten.com/200/202',
            text: 'Pepper',
        },
        3: {
            image: 'https://placekitten.com/200/203',
            text: 'Oscar',
        },
        4: {
            image: 'https://placekitten.com/200/204',
            text: 'Dusty',
        },
        5: {
            image: 'https://placekitten.com/200/205',
            text: 'Spooky',
        },
        6: {
            image: 'https://placekitten.com/200/210',
            text: 'Kiki',
        },
        7: {
            image: 'https://placekitten.com/200/215',
            text: 'Smokey',
        },
        8: {
            image: 'https://placekitten.com/200/220',
            text: 'Gizmo',
        },
        9: {
            image: 'https://placekitten.com/220/239',
            text: 'Kitty',
        },
    }
};

componentDidMount() {
    this.renderTimeOut()
}

renderTimeOut() {
    setInterval(() => {
        this.setState({data: [{image: null, text: 'bye'}, {image: null, text: 'heyaaa'}]});
    }, 5000);
}

render() {
    return (
        <View style={styles.container}>
            <Text style={styles.title}>React Native Sortable List</Text>
            <SortableList
                style={styles.list}
                contentContainerStyle={styles.contentContainer}
                data={this.state.data}
                renderRow={this._renderRow}
                manuallyActivateRows
            />
        </View>
    );
}

_renderRow = ({data, active}) => {
    return <Row data={data} active={active}/>
}

}

class Row extends Component {

constructor(props) {
    super(props);

    this._active = new Animated.Value(0);

    this._style = {
        ...Platform.select({
            ios: {
                transform: [{
                    scale: this._active.interpolate({
                        inputRange: [0, 1],
                        outputRange: [1, 1.1],
                    }),
                }],
                shadowRadius: this._active.interpolate({
                    inputRange: [0, 1],
                    outputRange: [2, 10],
                }),
            },

            android: {
                transform: [{
                    scale: this._active.interpolate({
                        inputRange: [0, 1],
                        outputRange: [1, 1.07],
                    }),
                }],
                elevation: this._active.interpolate({
                    inputRange: [0, 1],
                    outputRange: [2, 6],
                }),
            },
        })
    };
}

componentWillReceiveProps(nextProps) {
    if (this.props.active !== nextProps.active) {
        Animated.timing(this._active, {
            duration: 300,
            easing: Easing.bounce,
            toValue: Number(nextProps.active),
        }).start();
    }
}

render() {
    const {data, active} = this.props;

    return (
        <SwipeRow
            disableRightSwipe={true}
            rightOpenValue={-120}
            swipeToOpenPercent={5}
            swipeToClosePercent={5}
            style={{
                flex: 1,
                flexDirection: 'column',
                alignItems: 'center',
                justifyContent: 'center',
                height: 86,
                width: window.width
            }}
        >
            <View style={{flex: 1, width: window.width, height: 86}}/>
            <Animated.View style={[
                styles.row,
                this._style,
            ]}>
                <TouchableOpacity
                    style={{
                        flexDirection: 'row',
                        alignItems: 'center',
                        backgroundColor: '#fff',
                        height: 80,
                        borderRadius: 4,

                        ...Platform.select({
                            ios: {
                                width: window.width - 40 * 2,
                                shadowColor: 'rgba(0, 0, 0 ,0.2)',
                                shadowOpacity: 1,
                                shadowOffset: {height: 2, width: 2},
                                shadowRadius: 2
                            },

                            android: {
                                width: window.width - 40 * 2,
                                elevation: 0
                            }
                        })
                    }}
                    onLongPress={this.props.toggleRowActive}
                >
                    <Image source={{uri: data.image}} style={styles.image}/>
                    <Text style={styles.text}>{data.text}</Text>
                </TouchableOpacity>
            </Animated.View>
        </SwipeRow>
    );
}

}

const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#eee',

    ...Platform.select({
        ios: {
            paddingTop: 20,
        },
    }),
},

title: {
    fontSize: 20,
    paddingVertical: 20,
    color: '#999999',
},

list: {
    flex: 1,
},

contentContainer: {
    width: window.width,

    ...Platform.select({
        ios: {
            paddingHorizontal: 30,
        },

        android: {
            paddingHorizontal: 0,
        }
    })
},

row: {
    flexDirection: 'row',
    alignItems: 'center',
    backgroundColor: '#fff',
    padding: 16,
    height: 80,
    flex: 1,
    marginTop: 7,
    marginBottom: 12,
    borderRadius: 4,

    ...Platform.select({
        ios: {
            width: window.width - 30 * 2,
            shadowColor: 'rgba(0,0,0,0.2)',
            shadowOpacity: 1,
            shadowOffset: {height: 2, width: 2},
            shadowRadius: 2,
        },

        android: {
            width: window.width - 30 * 2,
            elevation: 0,
            marginHorizontal: 30,
        },
    })
},

image: {
    width: 50,
    height: 50,
    marginRight: 30,
    borderRadius: 25,
},

text: {
    fontSize: 24,
    color: '#222222',
},

});

karthick-t2s commented 5 years ago

I'm also facing the same problem.

Gslaughl commented 5 years ago

Same here, only on Android. Dragging more than one space makes the whole list flicker and jump as I continue to drag. Not using redux btw

matheusgrieger commented 5 years ago

Got the same issue on iOS, unfortunately.

NewBieBR commented 5 years ago

Same here on iOS, with:

vmaark commented 5 years ago

I have the same issue on iOS, when adding a new item, the view blinks.