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).