Apollo refetch不重新渲染组件

时间:2018-01-25 00:51:18

标签: reactjs react-native graphql apollo

我正在使用graphql从Web服务获取数据,我的客户端代码就是这个

import React, { Component } from 'react';
import {
    Platform,
    StyleSheet,
    Text,
    ActivityIndicator,
    View,
    FlatList,
    TouchableHighlight,
    TextInput,
    Button,
} from 'react-native';
import PropTypes from 'prop-types';
import { graphql, compose } from 'react-apollo';
import ZONES_QUERY from '../graphql/zones.query'


class ZonesScreen extends Component {


    render() {
        const { zones, loading, error } = this.props;


        if (loading) {
            return (
                <ActivityIndicator style={styles.activityIndicator} size='large' />
            )
        } else if (error) {
            return (
                <View style={styles.container}>
                    <Text>Unexcpeted Error</Text>
                    <Button title="retry" onPress={() => { this.props.refetch() }}></Button>

                </View>

            )
        } else {
            return (
                <View
                    style={styles.container}>
                    <FlatList
                        data={zones}
                        renderItem={({ item }) => ZoneRenderItem(item)}
                        keyExtractor={this.keyExtractor}

                    />
                </View>
            )
        }
    }

    //HELPER FUNCTIONS

    keyExtractor = item => item._id;
}

ZonesScreen.propTypes = {
    refetch: PropTypes.func,
}


const zonesQuery = graphql(ZONES_QUERY, {
    options: {
        forceFetch: true,
        fetchPolicy: 'network-only',
        notifyOnNetworkStatusChange: true,
    },
    props: ({ data: { loading, getRoutes, error, refetch } }) => ({
        loading,
        zones: getRoutes,
        refetch,
        error,
    }),
})



const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        backgroundColor: '#eee',
    },
    activityIndicator: {
        flex: 1,
        justifyContent: 'center',
    },
});

export default compose(
    zonesQuery,
)(ZonesScreen)

refetch无法正常工作,当我按下重试按钮时,它会获得响应,但组件未被重新加载。

区域是我从服务中获得的区域列表。

如您所见,我为查询设置了三个选项

forceFetch:true, fetchPolicy:'仅限网络', notifyOnNetworkStatusChange:true,

所有这些都是从github存储库中读取的

https://github.com/apollographql/apollo-client/issues/1622

UPDATE !!!!!!!

我发现使用来自'react-native-router-flux'的动作的解决方法基本上就是强制使用Actions.refresh强制渲染组件,传递道具作为参数来重新加载它们。见功能refetch = () => {。我还创建了一个refetching状态,告诉我们数据是否正在重新获取。

import React, { Component } from 'react';
import {
    Platform,
    StyleSheet,
    Text,
    ActivityIndicator,
    View,
    FlatList,
    TouchableHighlight,
    TextInput,
    Button,
} from 'react-native';
import PropTypes from 'prop-types';
import { graphql, compose } from 'react-apollo';
import ZONES_QUERY from '../graphql/zones.query


class ZonesScreen extends Component {

    constructor(props) {
        super(props)
        this.state = { refetching: false }
    }


    render() {
        const { zones, loading, error } = this.props;
        const { refetching } = this.state

        if (loading || refetching) {
            return (
                <ActivityIndicator style={styles.activityIndicator} size='large' />
            )
        } else if (error) {
            return (
                 <View style={styles.container}>
                    <Text>Unexcpeted Error</Text>
                    <Button title="retry" onPress={() => { this.refetch() }}></Button>

                </View>
            )
        } else {
            return (
                <View
                    style={styles.container}>
                    <FlatList
                        data={zones}
                        renderItem={({ item }) => ZoneRenderItem(item)}
                        keyExtractor={this.keyExtractor}
                    />
                </View>
            )
        }
    }

    //HELPER FUNCTIONS

    keyExtractor = item => item._id;

    refetch = () => {
        this.setState({ refetching: true });
        this.props.refetch()
            .then(() => { this.refreshComponent(false, this.props)
        })
            .catch(error => { this.refreshComponent(false, this.props); 
        })
    }

    refreshComponent = (refetching, props) => {
        this.setState({ refetching: refetching });
        Actions.refresh(props)
    }

}


const zonesQuery = graphql(ZONES_QUERY, {
    options:  {
        errorPolicy: 'ignore',
        fetchPolicy: 'network-only',
        notifyOnNetworkStatusChange: true,
    },
    props: ({ data: { loading, getRoutes, error, refetch, } }) => ({
        loading,
        zones: getRoutes,
        error,
        refetch,
    }),
})

const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        backgroundColor: '#eee',
    },
    activityIndicator: {
        flex: 1,
        justifyContent: 'center',
    },
});

export default compose(
    zonesQuery,
)(ZonesScreen)

0 个答案:

没有答案