Обновить компонент при открытии из ящика (реагировать на навигацию) - PullRequest
0 голосов
/ 05 марта 2019

EDIT: асинхронные вызовы теперь помещены в вызов 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>
        );
    }

Визуализация функций registered, notRegistered и onOpenFood и onOpenActivity для простоты опущена. Для функциональности обновления и вызовов API для работы у меня есть этот фрагмент кода (функции вызовов API находятся в отдельных файлах, это базовые запросы axios, GET и POST):

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 после повторной загрузки страницы? Страница, а также страницы, к которым переходят функции onOpenFood и onOpenActivity, являются частью StackNavigator, который сам является частью DrawerNavigator (реакции-навигации 3.3.2).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...