无法将 Redux-saga 与 Redux 集成
Failing to integrate Redux-saga with Redux
我是第一次尝试使用 Redux-saga,所以我有以下 sagas 文件:
backendAuth.js
import {all, call, fork, put, takeEvery} from "redux-saga/effects";
import {auth} from 'backend/backend';
import {
SIGNIN_USER,
SIGNOUT_USER,
SIGNUP_USER
} from "constants/ActionTypes";
import {showAuthMessage, userSignInSuccess, userSignOutSuccess, userSignUpSuccess} from "actions/Auth";
const createUserWithUsernamePasswordRequest = async (username, password) =>
await auth.createUserWithUsernameAndPassword(username, password)
.then(authUser => {
console.log('authUser: '+authUser);
return authUser;
})
.catch(error => error);
const signInUserWithUsernamePasswordRequest = async (username, password) =>
await auth.signInWithUsernameAndPassword(username, password)
.then(authUser => authUser)
.catch(error => error);
const signOutRequest = async () =>
await auth.signOut()
.then(authUser => authUser)
.catch(error => error);
function* createUserWithUsernamePassword({payload}) {
const {username, email, password} = payload;
try {
const signUpUser = yield call(createUserWithUsernamePasswordRequest, username, email, password);
if (signUpUser.message) {
yield put(showAuthMessage(signUpUser.message));
} else {
localStorage.setItem('user_id', signUpUser.user.uid);
yield put(userSignUpSuccess(signUpUser.user.uid));
}
} catch (error) {
yield put(showAuthMessage(error));
}
}
function* signInUserWithUsernamePassword({payload}) {
const {username, password} = payload;
try {
const signInUser = yield call(signInUserWithUsernamePasswordRequest, username, password);
if (signInUser.message) {
yield put(showAuthMessage(signInUser.message));
} else {
localStorage.setItem('user_id', signInUser.user.uid);
yield put(userSignInSuccess(signInUser.user.uid));
}
} catch (error) {
yield put(showAuthMessage(error));
}
}
function* signOut() {
try {
const signOutUser = yield call(signOutRequest);
if (signOutUser === undefined) {
localStorage.removeItem('user_id');
yield put(userSignOutSuccess(signOutUser));
} else {
yield put(showAuthMessage(signOutUser.message));
}
} catch (error) {
yield put(showAuthMessage(error));
}
}
export function* createUserAccount() {
yield takeEvery(SIGNUP_USER, createUserWithUsernamePassword);
}
export function* signInUser() {
yield takeEvery(SIGNIN_USER, signInUserWithUsernamePassword);
}
export function* signOutUser() {
yield takeEvery(SIGNOUT_USER, signOut);
}
export default function* rootSaga() {
yield all([
fork(signInUser),
fork(createUserAccount),
fork(signOutUser)
]);
}
这是对 api 执行异步查询的文件:
backend.js
import axios from 'axios';
const backendServer = 'http://localhost:8000/';
const signInEndpoint = backendServer + 'api/token_auth/';
const signInWithUsernameAndPassword = (username, password) => {
axios.post(backendServer+"api/token_auth/", {
username: username,
password: password
})
.then(Response => {
console.log('Response: '+Response)
return Response;
})
.catch(Error => Error);
}
export const auth = {
signInWithUsernameAndPassword: signInWithUsernameAndPassword
}
通过axios很好的执行了ajax,达到了backend.js
中的console.log()
,但是console.log()
在 backendAuth
中不是,我在控制台中收到以下错误:
index.js:1375 Invariant Violation: Objects are not valid as a React child (found: TypeError: Cannot read property 'then' of undefined). If you meant to render a collection of children, use an array instead.
我认为问题在于我在 backend.js
的 ajax 中定义 then
的值 return 的方式,但我很漂亮前端开发新手,所以不太确定。
根本原因是一个简单的修复 - 您正在为 signInWithUsernameAndPassword
箭头函数的主体使用显式块,因此您需要使用显式 return
。由于您没有 return
声明函数 returns undefined
级联导致整体问题。
快速修复只是将函数更新为:
const signInWithUsernameAndPassword = (username, password) => {
return axios.post(backendServer+"api/token_auth/", {
username: username,
password: password
})
.then(Response => {
console.log('Response: '+Response)
return Response;
})
.catch(Error => Error);
}
现在了解您现在看到的最终错误:由于 signInWithUsernameAndPassword
returns undefined
,您最终进入了 catch
块 signInWithUsernamePassword
在 backendAuth.js
中,由于调用 undefined
的类型错误。然后在 signInUserWithUsernamePasswordRequest
中。 catch
块中的错误是一个 Error
实例,而不是纯字符串。我假设您随后在反应组件树中的某处显示传递给 showAuthError
的 error
,但是 Error
实例不是可以有效呈现的东西。您可以先尝试在其上调用 toString()
以显示未来的错误,而不是导致渲染错误。
我是第一次尝试使用 Redux-saga,所以我有以下 sagas 文件:
backendAuth.js
import {all, call, fork, put, takeEvery} from "redux-saga/effects";
import {auth} from 'backend/backend';
import {
SIGNIN_USER,
SIGNOUT_USER,
SIGNUP_USER
} from "constants/ActionTypes";
import {showAuthMessage, userSignInSuccess, userSignOutSuccess, userSignUpSuccess} from "actions/Auth";
const createUserWithUsernamePasswordRequest = async (username, password) =>
await auth.createUserWithUsernameAndPassword(username, password)
.then(authUser => {
console.log('authUser: '+authUser);
return authUser;
})
.catch(error => error);
const signInUserWithUsernamePasswordRequest = async (username, password) =>
await auth.signInWithUsernameAndPassword(username, password)
.then(authUser => authUser)
.catch(error => error);
const signOutRequest = async () =>
await auth.signOut()
.then(authUser => authUser)
.catch(error => error);
function* createUserWithUsernamePassword({payload}) {
const {username, email, password} = payload;
try {
const signUpUser = yield call(createUserWithUsernamePasswordRequest, username, email, password);
if (signUpUser.message) {
yield put(showAuthMessage(signUpUser.message));
} else {
localStorage.setItem('user_id', signUpUser.user.uid);
yield put(userSignUpSuccess(signUpUser.user.uid));
}
} catch (error) {
yield put(showAuthMessage(error));
}
}
function* signInUserWithUsernamePassword({payload}) {
const {username, password} = payload;
try {
const signInUser = yield call(signInUserWithUsernamePasswordRequest, username, password);
if (signInUser.message) {
yield put(showAuthMessage(signInUser.message));
} else {
localStorage.setItem('user_id', signInUser.user.uid);
yield put(userSignInSuccess(signInUser.user.uid));
}
} catch (error) {
yield put(showAuthMessage(error));
}
}
function* signOut() {
try {
const signOutUser = yield call(signOutRequest);
if (signOutUser === undefined) {
localStorage.removeItem('user_id');
yield put(userSignOutSuccess(signOutUser));
} else {
yield put(showAuthMessage(signOutUser.message));
}
} catch (error) {
yield put(showAuthMessage(error));
}
}
export function* createUserAccount() {
yield takeEvery(SIGNUP_USER, createUserWithUsernamePassword);
}
export function* signInUser() {
yield takeEvery(SIGNIN_USER, signInUserWithUsernamePassword);
}
export function* signOutUser() {
yield takeEvery(SIGNOUT_USER, signOut);
}
export default function* rootSaga() {
yield all([
fork(signInUser),
fork(createUserAccount),
fork(signOutUser)
]);
}
这是对 api 执行异步查询的文件: backend.js
import axios from 'axios';
const backendServer = 'http://localhost:8000/';
const signInEndpoint = backendServer + 'api/token_auth/';
const signInWithUsernameAndPassword = (username, password) => {
axios.post(backendServer+"api/token_auth/", {
username: username,
password: password
})
.then(Response => {
console.log('Response: '+Response)
return Response;
})
.catch(Error => Error);
}
export const auth = {
signInWithUsernameAndPassword: signInWithUsernameAndPassword
}
通过axios很好的执行了ajax,达到了backend.js
中的console.log()
,但是console.log()
在 backendAuth
中不是,我在控制台中收到以下错误:
index.js:1375 Invariant Violation: Objects are not valid as a React child (found: TypeError: Cannot read property 'then' of undefined). If you meant to render a collection of children, use an array instead.
我认为问题在于我在 backend.js
的 ajax 中定义 then
的值 return 的方式,但我很漂亮前端开发新手,所以不太确定。
根本原因是一个简单的修复 - 您正在为 signInWithUsernameAndPassword
箭头函数的主体使用显式块,因此您需要使用显式 return
。由于您没有 return
声明函数 returns undefined
级联导致整体问题。
快速修复只是将函数更新为:
const signInWithUsernameAndPassword = (username, password) => {
return axios.post(backendServer+"api/token_auth/", {
username: username,
password: password
})
.then(Response => {
console.log('Response: '+Response)
return Response;
})
.catch(Error => Error);
}
现在了解您现在看到的最终错误:由于 signInWithUsernameAndPassword
returns undefined
,您最终进入了 catch
块 signInWithUsernamePassword
在 backendAuth.js
中,由于调用 undefined
的类型错误。然后在 signInUserWithUsernamePasswordRequest
中。 catch
块中的错误是一个 Error
实例,而不是纯字符串。我假设您随后在反应组件树中的某处显示传递给 showAuthError
的 error
,但是 Error
实例不是可以有效呈现的东西。您可以先尝试在其上调用 toString()
以显示未来的错误,而不是导致渲染错误。