Я новичок в React Native, и в настоящее время я пытаюсь получить учетные данные с веб-сайта и сохранить их в памяти устройства. Однако я сталкиваюсь с некоторыми проблемами!
Мой поток:
Когда приложение запускается, оно проверяет asyncStorage на наличие учетных данных.
Если да, то сразу заходим в приложение. В противном случае мы заходим в RootStackScreen (он же экран входа в систему) *** (проблема №1)
(ВХОД) Пользователь вводит свой логин в текстовый ввод, который будет сохранен в useState.
С помощью функции 'loginHandle' запрос выборки вызывается с использованием информации из useState, и мы устанавливаем Credential с возвращенными данными. ** (проблема № 2)
Приложение должно выполнить повторную визуализацию и увидеть, что есть учетные данные, и загрузиться на главный экран. *** (выпуск №3)
Однако я сталкиваюсь с двумя проблемами.
*** Даже когда asyncStorage действительно содержит учетные данные, когда я проверяю appLoad.credentials в return (...), он возвращает значение null. Однако он возвращает правильное значение в моем useEffect (). Я думал, что с помощью useEffect () я вызываю функции во время ComponentsDidMount, перед отрисовкой экрана. Так разве appLoad.credentials не должен содержать строку?
В моем console.log (учетные данные) Он всегда на шаг отстает. Т.е. Я нажимаю кнопку входа в систему один раз. Журнал консоли вернет значение null. Однако я подумал, что, поскольку console.log () находится после команды fetch, учетные данные должны быть установлены перед вызовом console.log!
Как мне заставить приложение повторно отрендерить? Я видел в сети, что касается повторного рендеринга, но слышал, что это плохо!
App.js
import AsyncStorage from '@react-native-community/async-storage';
...
export default function App() {
const STORAGE_KEY = '@deviceCredentials';
const [data, setData] = useState('');
const appLoad = {
isLoading: true,
credentials: null
};
//Runs during ComponentsDidMount
useEffect(() => {
setTimeout(async () => {
//In 1000ms try to get credentials
try {
appLoad.credentials = await AsyncStorage.getItem(STORAGE_KEY);
console.log(appLoad.credentials);
} catch (e) {
console.log(e);
}
}, 1000);
}, []);
//Render
return (
<NavigationContainer>
{/* If credentials is not null then we can go straight into Main screen,
otherwise we go to Login Screen */}
{appLoad.credentials !== null ? (
<Drawer.Navigator drawerContent={props => <DrawerContent {...props} />}>
<Drawer.Screen name="MusteringDrawer" component={MainTabScreen} />
</Drawer.Navigator>
)
:
<RootStackScreen />
}
</NavigationContainer>
);
};
SignIn.js
...
...
const [data, setData] = useState({
username: '',
password: '',
...
})
const [credential, setCredential] = useState({ data: null });
const STORAGE_KEY = '@deviceCredentials';
...
...
//Handles user data
const handleValidUser = (val) => {
setData({
...data,
username: val,
});
}
const loginHandle = () => {
fetch(url + data.password + data.username)
.then(x => x.text())
.then(y => {
setCredential({ data: y });
});
console.log(credential);
AsyncStorage.setItem(STORAGE_KEY, credential);
}
return(
<Text>Username</Text>
<TextInput
placeholder="Your Username"
onChangeText={(val) => handleValidUser(val)}
onEndEditing={(e) => handleValidUser(e.nativeEvent.text)}
/>
<Text>Password</Text>
<TextInput
placeholder="Your Password"
onChangeText={(val) => handlePasswordChange(val)}
/>
<View style={styles.button}>
<TouchableOpacity onPress={() => { loginHandle(); }}>
<Text>Sign In</Text>
</TouchableOpacity>
</View>