从抽屉打开时刷新组件(反应式导航)

时间:2019-03-05 14:09:26

标签: react-native react-navigation-drawer

编辑:异步调用现在已放置在axios.all()调用中,以加快处理速度。问题依旧。

在我的应用程序中,当在“登录”屏幕上按注销时,将删除设备上存储的令牌。

Login.js

    async resetKey() {
        try {
            await AsyncStorage.removeItem('@MySuperStore:key');
            this.setState({
                token: null,
                loggedIn: false,
            });
        } catch (error) {
            this.setState({
                token: null,
                loggedIn: false,
            });
        }
    }

现在,我想在另一页中使用此事实,在此我将渲染基于道具loggedIn。如果true已登录,那么我正在渲染活动,并以绿色或红色框表示用户是否已注册该活动。这都是相当琐碎的,并且可以正常工作:

    if (this.state.loggedIn) {
        return (
            <ScrollView refreshControl={
                <RefreshControl refreshing={this.state.refreshing} onRefresh={this.onRefresh.bind(this)} />
            }>
                <Loader loading={this.state.loading} />

                <Text style={styles.foodHeader}>Activiteiten</Text>
                {this.state.activities.map((activity) => (
                    <TouchableOpacity key={activity.id} onPress={() => this.onOpenActivity(activity)} style={styles.foodActivityField}>
                        <Text>{`${activity.name}`}</Text>
                        <View>
                            {this.showRegistered(activity.id) ? registered : notRegistered}
                        </View>
                    </TouchableOpacity>
                ))}

                <Text style={styles.foodHeader}>Eten</Text>
                {this.state.foods.map((food) => (
                    <TouchableOpacity key={food.id} onPress={() => this.onOpenFood(food)} style={styles.foodActivityField}>
                        <Text>{`${food.name}`}</Text>
                        <View>
                            {this.showRegistered(food.id) ? registered : notRegistered}
                        </View>
                    </TouchableOpacity>
                ))}

            </ScrollView>
        );
    }

但是,当用户刚刚注销时,不应显示此内容。在这种情况下,它应该显示一个简单的文本,即“您必须登录才能查看活动”。

    else {
        {/** User is not logged in */ }
        return (
            <ScrollView refreshControl={
                <RefreshControl refreshing={this.state.refreshing} onRefresh={this.onRefresh.bind(this)}  />
            }>
                <Loader loading={this.state.loading} />
                <Text>You have to be logged in to view activities</Text>
            </ScrollView>
        );
    }

为简单起见,省略了registerednotRegistered以及onOpenFoodonOpenActivity函数的呈现。关于刷新的功能和可以正常工作的API调用,我有这段代码(API调用的功能位于单独的文件中,这些都是基本的axios请求,GETPOST均如此) :

constructor(props) {
    super(props);
    this.state = {
        loading: true,
        refreshing: false,
        activities: [],
        foods: [],
        registered: []
    }
    this.getData
}

/* Handles the action necessary to refresh */
onRefresh = () => {
    this.setState({ refreshing: true });
    this.getData().then(() => {
        this.setState({ refreshing: false });
    });
}

async componentDidMount() {
    // Do the necessary API calls
    this.getData();
}

getData = async () => {

    this.setState({loading: true})
    /* Get token from storage */
    try {
        console.log('trying to get key...')
        const value = await AsyncStorage.getItem('@MySuperStore:key');
        if (value) {
            this.setState({
                token: value,
                loggedIn: true
            });

            /* Retrieve activities */
            const activities = await getActivities();
            this.setState({ activities });

            /* Retrieve food */
            const foods = await getFood();
            this.setState({ foods });

            /* Retrieve the activity ID's the user is registered for */
            const registered = await getRegistered(this.state.token);
            this.setState({ registered });
            this.setState({ loading: false })

        } else {
            this.setState({
                token: null,
                loggedIn: false,
                loading: false
            });
        }
    } catch (error) {
        this.setState({
            token: null,
            loggedIn: false
        });
        console.log("help")
    }


}

现在的问题是,在重新打开页面时看不到this.state.registered更改,导致页面显示不正确。由于重置了整个状态,因此刷新页面是可行的。如何解决?是否有办法例如在再次加载页面时调用onRefresh?该页面以及功能onOpenFoodonOpenActivity导航到的页面都是StackNavigator的一部分,而StackNavigator本身就是DrawerNavigator的一部分(反应导航3.3.2)。

1 个答案:

答案 0 :(得分:2)

如果有人偶然发现了这个问题,您可能需要查看结合了侦听器的 useEffect 钩子之类的东西。在这种情况下,它看起来像这样;

useEffect(()=> {
  const unsubscribe = navigation.addListener('focus', () => {
    onRefresh();
  });

  return unsubscribe;
}, [navigation]);

这确保在页面焦点返回时调用 onRefresh 函数,并且在导航属性中的某些内容发生更改时调用该函数。这是一个老问题,所以我没有在代码中调整它,但在较新的项目中,这似乎工作得很好