Quantcast
Channel: Active questions tagged react-native+ios - Stack Overflow
Viewing all articles
Browse latest Browse all 16750

How can I sync two flatList scroll position in react native

$
0
0

enter image description here

As you can see in the picture above, there is a vertical list of two columns. I have developed two flatLists because I can not style photos with different height on one line with the flatList column option.

I want two flatLists to have the same scroll position.

I wrapped two FlatList component with to synchronize scrolling. But there is a problem here. The scrollView ignores the infinity scroll and calls the pagination objects all at once. There is a performance problem.

How can I solve this problem?

here is my component code

import React from 'react';import { View, Platfrom, Text, StyleSheet, AsyncStorage, TouchableOpacity, Image, FlatList, Button, Dimensions, ScrollView, ListView } from 'react-native';import Icon from 'react-native-vector-icons/FontAwesome';import { NavigationActions } from 'react-navigation';import { connect } from 'react-redux';import moment from 'moment';import * as settings from '../../config/settings';import Menu from '../menu';import headerStyles from '../../styles/common/header';import textStyles from '../../styles/common/text';import containerStyles from '../../styles/common/container';import imageStyles from '../../styles/common/image';import boxStyles from '../../styles/common/box';import objectStyles from '../../styles/common/object';import commonStyles from '../../styles/common/common';import colorStyles from '../../styles/common/color';const window = Dimensions.get('window');const styles = StyleSheet.create({    listView: {        paddingTop: 20,        backgroundColor: '#FFFFFF',    },    fullScreen: {        flex: 1,        marginBottom: 50,    },    floatView: {        position: 'absolute',        width: '90%',        marginLeft: '5%',        height: 100,        bottom: -50,    },});const phoneWidth = Dimensions.get('window').widthclass PurchaseListScreen extends React.Component {    static navigationOptions = ({ navigation }) => {        const { params = {} } = navigation.state        return {            title: '중고명품구매',            headerStyle: headerStyles.header,            headerTitleStyle: headerStyles.headerTitle,            headerRight: <Icon name="bars" size={30} color="#333" onPress={() => { params.showModal() }} style={{ padding: 10 }} />,        }    }    constructor(props) {        super(props);        this.state = {            user_token: '',            refreshing: false,            isModalVisible: false,            leftColumneData: [],            rightColumneData: [],            leftNextKey: '',            rightNextKey: '',        };        this.hideModal = this.hideModal.bind(this);    }    componentDidMount() {        this.props.navigation.setParams({ showModal: this.showModal });        this.purchaseListService();    }    showModal = () => this.setState({ isModalVisible: true })    hideModal = () => this.setState({ isModalVisible: false })    navigate1 = (item) => {        console.log('click navigate1');        const navigate1 = NavigationActions.navigate({            routeName: "home",        });        this.props.navigation.dispatch(navigate1);    };    purchaseListService = async () => {        if (this.props.isLoggedIn) {            let user_info = await AsyncStorage.getItem('user_info');            get_user_token = JSON.parse(user_info).key;            this.setState({ user_token: get_user_token });            const api_uri1 = settings.base_uri +'purchase-product/odd/'            const request1 = {                method: 'GET',                headers: {'Authorization': 'Token '+ get_user_token,'Accept': 'application/json','Content-Type': 'application/json',                }            }            const api_uri2 = settings.base_uri +'purchase-product/even/'            const request2 = {                method: 'GET',                headers: {'Authorization': 'Token '+ get_user_token,'Accept': 'application/json','Content-Type': 'application/json',                }            }            fetch(api_uri1, request1)                .then(res => res.json())                .then(res => {                    this.setState({                        leftColumneData: [...res.results],                        leftNextKey: res.next                    })                })                .catch((error) => {                    console.error(error);                })            fetch(api_uri2, request2)                .then(res => res.json())                .then(res => {                    this.setState({                        rightColumneData: [...res.results],                        rightNextKey: res.next,                    })                })                .catch((error) => {                    console.error(error);                })        } else {            const api_uri1 = settings.base_uri +'purchase-product/odd/'            const request1 = {                method: 'GET',                headers: {'Accept': 'application/json','Content-Type': 'application/json',                }            }            const api_uri2 = settings.base_uri +'purchase-product/even/'            const request2 = {                method: 'GET',                headers: {'Accept': 'application/json','Content-Type': 'application/json',                }            }            fetch(api_uri1, request1)                .then(res => res.json())                .then(res => {                    this.setState({                        leftColumneData: [...res.results],                        leftNextKey: res.next,                    })                })                .catch((error) => {                    console.error(error);                })            fetch(api_uri2, request2)                .then(res => res.json())                .then(res => {                    this.setState({                        rightColumneData: [...res.results],                        rightNextKey: res.next,                    })                })                .catch((error) => {                    console.error(error);                })        }    }    onEndReachedService = () => {        console.log('run onEndReachedService');        if (this.props.isLoggedIn && this.state.leftNextKey) {            const api_uri1 = this.state.leftNextKey            const request1 = {                method: 'GET',                headers: {'Authorization': 'Token '+ this.state.user_token,'Accept': 'application/json','Content-Type': 'application/json',                }            }            const api_uri2 = this.state.rightNextKey            const request2 = {                method: 'GET',                headers: {'Authorization': 'Token '+ this.state.user_token,'Accept': 'application/json','Content-Type': 'application/json',                }            }            fetch(api_uri1, request1)                .then(res => res.json())                .then(res => {                    this.setState({                        leftColumneData: [...this.state.leftColumneData, ...res.results],                        leftNextKey: res.next                    })                })                .catch((error) => {                    console.error(error);                })            fetch(api_uri2, request2)                .then(res => res.json())                .then(res => {                    this.setState({                        rightColumneData: [...this.state.rightColumneData, ...res.results],                        rightNextKey: res.next,                    })                })                .catch((error) => {                    console.error(error);                })        } else if (!this.props.isLoggedIn && this.state.leftNextKey){            const api_uri1 = this.state.leftNextKey            const request1 = {                method: 'GET',                headers: {'Accept': 'application/json','Content-Type': 'application/json',                }            }            const api_uri2 = this.state.rightNextKey            const request2 = {                method: 'GET',                headers: {'Accept': 'application/json','Content-Type': 'application/json',                }            }            fetch(api_uri1, request1)                .then(res => res.json())                .then(res => {                    console.log('update res1', res);                    this.setState({                        leftColumneData: [...this.state.leftColumneData, ...res.results],                        leftNextKey: res.next,                    })                })                .catch((error) => {                    console.error(error);                })            fetch(api_uri2, request2)                .then(res => res.json())                .then(res => {                    console.log('update res2', res);                    this.setState({                        rightColumneData: [...this.state.rightColumneData, ...res.results],                        rightNextKey: res.next,                    })                })                .catch((error) => {                    console.error(error);                })        }    }    likeService = async (pk, column) => {        let user_info = await AsyncStorage.getItem('user_info');        user_token = JSON.parse(user_info).key;        const api_uri = settings.base_uri +'purchase-product/'+ pk +'/like/'        var request = {            method: 'POST',            headers: {'Authorization': 'Token '+ user_token,'Accept': 'application/json','Content-Type': 'application/json',            }        };        fetch(api_uri, request)            .then(res => {                if(column=='left'){                    var items = this.state.leftColumneData                    for (i=0; i<items.length; i++) {                        let item = items[i]                        if (item.id==pk) {                            item.is_liked = !item.is_liked                            items[i] = item;                            this.setState({ leftColumneData: items })                        }                    }                } else {                    var items = this.state.rightColumneData                    for (i = 0; i < items.length; i++) {                        let item = items[i]                        if (item.id == pk) {                            item.is_liked = !item.is_liked                            items[i] = item;                            this.setState({ rightColumneData: items })                        }                    }                }            })            .catch((error) => {                console.error(error);            });    }    renderLabel = (text) => {        if (text) {            return (<View style={{ backgroundColor: 'red', paddingVertical: 2, marginLeft: 3, marginTop: 5, marginBottom: 8, paddingHorizontal: 4 }}><Text style={{ color: 'white', fontSize: 9, fontWeight: '400' }}>{text}</Text></View>            )        } else {            return (<View style={{ paddingVertical: 2, marginTop: 5, marginBottom: 8, }}></View>            )        }    }    renderList = (item, column) => {        return(<View><View style={{                     flex: 1,                     borderColor: 'rgb(136, 136, 136)',                     borderWidth: 1,                     marginLeft: 15,                     marginTop: 15,                    backgroundColor: 'white',                    }}><TouchableOpacity onPress={()=>{}}>                    {item.is_vertical?<Image                            source={{ uri: item.first_thumbnail }}                            style={{ flex:1, height: 210 }}/>                        :<Image                            source={{ uri: item.first_thumbnail }}                            style={{ flex: 1, height: 130 }} />                    }</TouchableOpacity><View style={{ flex: 1 }}><View style={{ flexDirection: 'row' }}><TouchableOpacity style={{ flex: 4 }}><Text style={{                                    fontSize: 14,                                    fontWeight: '600',                                    color: 'rgb(35, 31, 32)',                                    marginTop: 10,                                    marginLeft: 8                                }}>{item.name}</Text><Text style={{                                    fontSize: 12,                                    fontWeight: '500',                                    color: 'rgb(35, 31, 32)',                                    marginLeft: 8,                                    marginTop: 8                                }}>{item.partner.biz_name}</Text><View style={{ flexDirection: 'row', marginLeft: 6 }}>                                    {this.renderLabel(item.product_type_str)}                                    {this.renderLabel(item.city.name)}</View></TouchableOpacity><View                                style={{ flex: 1, marginTop: 10, marginRight: 2, alignItems: 'center' }}>                                {this.props.isLoggedIn ? <View>                                        {item.is_liked ?<Icon                                                name="heart" size={17} color="red"                                                onPress={() => {                                                    this.likeService(item.id, column);                                                }} />                                            : <Icon name="heart-o" size={17} color="red"                                                onPress={() => {                                                    this.likeService(item.id, column);                                                }} />                                        }</View> : <View><Icon name="heart-o" size={17} color="red"                                            onPress={() => {                                                console.log('press heart', column);                                            }} /></View>}</View></View><View style={[ colorStyles.greenBackground,                            {                                flex: 1,                                borderTopWidth: 1,                                borderColor: 'rgb(136, 136, 136)',                                padding: 5,                                paddingRight: 10,                            }]}><Text style={{                                 textAlign: 'right',                                fontSize: 14,                                fontWeight: '500',                                color: 'rgb(35, 31, 32)',                            }}>                                {(item.price).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}원 {item.id}</Text></View></View></View></View>        )    }    render() {           return (<View style={{ flex: 1 }}><Menu hideModal={this.hideModal.bind(this)} isVisible={this.state.isModalVisible} navigation={this.props.navigation} /><View style={{ flexDirection: 'row' }}><FlatList                        style={{ flex: 1 }}                        showsVerticalScrollIndicator={false}                        initialNumToRender={20}                        onEndReachedThreshold={1}                        onEndReached={this.onEndReachedService}                        refreshing={this.state.refreshing}                        onRefresh={this.purchaseListService.bind(this)}                        data={this.state.leftColumneData}                        renderItem={({ item }) => this.renderList(item, column='left')}                        keyExtractor={(item) => item.id}                    /><FlatList                        style={{ flex: 1, paddingRight: 15  }}                        showsVerticalScrollIndicator={false}                        refreshing={this.state.refreshing}                        onRefresh={this.purchaseListService.bind(this)}                        data={this.state.rightColumneData}                        renderItem={({ item }) => this.renderList(item, column='right')}                        keyExtractor={(item) => item.id}                    /></View></View>        )    }}const mapStateToProps = state => ({    isLoggedIn: state.loginReducer.isLoggedIn})const PurchaseList = connect(mapStateToProps, null)(PurchaseListScreen);export default PurchaseList;

Viewing all articles
Browse latest Browse all 16750

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>