【发布时间】:2023-03-24 05:14:01
【问题描述】:
我正在制作非常简单的登录应用程序来学习 react 和 react-native,我的目标是获取用户输入,然后将这些值与包含用户和密码值的自定义假 api 文件进行比较,然后保存在 AsyncStorage (或localStorage)进行身份验证。所以我在互联网上搜索我要做什么,这是一个与我正在寻找的匹配的东西,但是我真的不明白这段代码是如何工作的。在这段代码中,有些事情让我困惑了一周,我脑子里有很多问题,所以我真的需要一些帮助。代码如下:
首先他的代码中有这样的 Redux Action
//Action.js
export const LoginRequested = (username,password) => {
return {
type: 'LOG_IN_REQUEST',
data: {
username,
password,
},
};
};
export const LoginSuccessed = (data) => {
return {
type: 'LOGIN_SUCCESS',
data,
};
};
export const LoginFailed = (data) => {
return {
type: 'LOG_IN_FAILURE',
data,
};
};
export const Logout = (data) => {
return {
type: 'LOG_OUT',
data
};
};
但让我困惑的是
问题 1: 这里的data 是什么?这个data 是干什么用的?
我的意思是我可以理解在LoginRequested,数据是用户名和密码,所以我猜用户名和密码存储在这里,但在loginSuccessed 和LoginFailed,我不明白,这里的数据是什么
这里是减速器
const initialState = {
isLoading: false,
authen: false
};
export const loginReducer = (state = initialState, action) => {
switch (action.type) {
case 'LOG_IN_REQUEST':
{
//console.log('action : LOG IN REQUEST');
return {
isLoading: true,
authen: false
}
}
case 'LOG_IN_SUCCESS':
{
//console.log('action : LOG IN SUCCESS');
return {
isLoading: false,
authen: true
};
}
case 'LOG_IN_FAILURE':
{
//console.log('action : LOG IN FAILURE');
return initialState;
}
case 'LOG_OUT':
{
//console.log('action : LOG OUT');
return initialState;
}
default:
return state;
}
};
对于reducer,所以:
问题 2: isLoading 和 authen( maybe authentication) 是做什么的??。
我可以理解它显示为登录状态,对吗?但我无法链接他如何使用那里的代码(我看到他在下面的传奇中使用过一次'LOGIN_SUCCESS',但我不明白)
这里是商店:
//store.js
const sagaMiddleware = createSagaMiddleware();
const store = createStore(rootReducer, applyMiddleware(sagaMiddleware)); //rootReducer is a combined reducer file, i don't show it here, but he have only one Reducer like above code
sagaMiddleware.run(rootSaga);
export default store;
这个我明白了,redux就是这样应用中间件的。
现在是佐贺部分
//saga.js
import { Alert } from 'react-native';
import { call, put, takeLatest } from 'redux-saga/effects';
//import axios from 'axios';
import { fetchLoginData } from '../../server/loginApi';
export function* loginMainSaga() {
yield takeLatest('LOG_IN_REQUEST', loginSaga);
}
function* saveDataToStorage(data) {
try {
AsyncStorage.setItem(
'userData',
JSON.stringify({
username: data.username,
password: data.password }))
} catch(e) {
console.log('error save to Storage');
}
};
function* loginSaga(action) {
const response = yield call(fetchLoginData);
const resData = JSON.parse(JSON.stringify(response));
const usernameAuth = String(resData.data[0].username);
const passwordAuth = String(resData.data[0].password);
if (String(action.data.username) === usernameAuth)
{
if (String(action.data.password) === passwordAuth)
{
//console.log('loginSaga LOG_IN_SUCCESS');
yield put({type: 'LOG_IN_SUCCESS'});
saveDataToStorage(action.data);
}
else
{
const error = 'Password is incorrect'
Alert.alert('Failed', error, [{ text: 'Ok', style: 'cancel' }] );
//console.log('loginSaga LOG_IN_FAILURE');
yield put({type: 'LOG_IN_FAILURE'});
}
} else {
const error = 'Username is incorrect'
Alert.alert('Failed', error, [{ text: 'Ok', style: 'cancel' }] );
//console.log('loginSaga LOG_IN_FAILURE');
yield put({type: 'LOG_IN_FAILURE'});
}
}
我可以理解,loginMainSaga() 是获取最新的username 和password 存储在redux 中,并使用loginSaga 与Json 文件中的进行比较。 SaveDatatoStorage 表示您将用户名和密码保存到AsyncStorage。
问题3:我上面的逻辑对吗?而loginSaga函数中的action这里是随机变量字还是直接指向action in redux reducer?
而最令人困惑的部分是loginScreen:
他将代码拆分为不同的组件,只是Formik的基本样式和组件,详细here:
这里是登录界面
function LoginScreen(props) {
const dispatch = useDispatch();
const loginHandler =({username, password}) => {
dispatch(
LoginRequested(username,password)
);
};
const isLoading = useSelector(state => {
//console.log('state.Login.isLoading ' + state.Login.isLoading);
return state.Login.isLoading;
});
return(
<Screen style={styles.container}>
<MaterialCommunityIcons name="wechat" color="black" size={200} />
<Text style={styles.title}>SIGN IN HERE</Text>
<AppForm
initialValues={{username: '', password: ''}}
onSubmit={loginHandler}
validationSchema={validateSchema}>
<AppFormField
name="username"
placeholder="Username"
icon="account"
autoCapitalize="none"
autoCorrect={false}
textContentType="nickname"
width="75%"
></AppFormField>
<AppFormField
name="password"
placeholder="Password"
icon="lock"
autoCapitalize="none"
autoCorrect={false}
secureTextEntry
textContentType="password"
width="75%"></AppFormField>
{isLoading ?
(
<ActivityIndicator size="large" color={'black'} />
) : (
<SubmitBtn title="Sign in" color={'black'} width="75%" />
)}
</AppForm>
<View style={styles.registerContainer}>
<Text style={{color: 'black'}}>Don't have an account?</Text>
<Text style={{color: 'black'}} onPress={() => null}> SIGN UP </Text>
</View>
</Screen>
);
}
我不明白他怎么能得到user和password,
我在这个文件中的第一个问题是:
问题4:为什么loginHandler const 在({username,password}) 中有{},为什么不使用(username,password)?
而最让我头疼的是这周无法停止思考:
问题5:他如何在onSubmit时得到user和password????他使用loginHandler,但是他如何添加username和password,他如何捕获哪个输入是username,即password,如果我有3个表单输入,这怎么处理? formik onSubmit有什么特别之处吗????
这里是完整代码:FULL CODE
请帮助,您的帮助现在对我来说非常宝贵,也许可以解决像我这样的新人的问题。非常感谢你
【问题讨论】:
-
请帮忙:((
标签: reactjs react-native react-redux react-hooks redux-saga