javascript - 当调用API的函数在类中定义时,如何通过效果调用从redux-saga调用API
问题描述
我正在尝试通过 redux-saga 的效果调用来调用 API,但是何时开始调用 api 会引发错误。Cannot read property 'post' of null
真的很奇怪,因为我创建了一个简单的函数来测试我的呼叫工作示例:
function requestGetUser() {
return axios.request({
method: 'get',
url: 'https://my-json-server.typicode.com/atothey/demo/user',
})
}
export function* fetchLoginSaga(action) {
const { data } = yield call(requestGetUser)
yield put(login({ id: data.id, name: data.firstName }))
}
export function* watcherSaga() {
yield takeLatest(fetchLogin.type, fetchLoginSaga)
}
并且上面的这个例子有效
但是当我尝试从效果调用内部的类调用 API 时不起作用
// Depedencies
import axios from 'axios'
export default class BaseService {
/**
* Default http request instane
* @type { Axios.Instance }
*/
instance
/**
* Creates an instance of BaseService.
* @param { String } endpoint To manipulates the operations.
* @param { String } [baseUrl= ] The base url.
*/
constructor(endpoint, baseURL = process.env.BASE_URL) {
this.endpoint = endpoint
this.instance = axios.create({ baseURL })
this.instance.interceptors.response.use(this.responseInterceptor, this.handleResponseError)
}
/**
* Intercepts every response.
* @param { Object } response The response.
* @returns { Promise<Object> }
*/
responseInterceptor = response => response.data
/**
* Intercepts every error on response.
* @param { Object } error The respone error.
* @returns { Promise<Object> }
*/
handleResponseError = error => {
const {
response: {
data: { message },
},
} = error
return Promise.reject(new Error(message))
}
/**
* Make a post request with data.
* @param { Object } [data={}] The data to send as body.
* @param { Object } [requestParams={}] The params to make the request.
* @return { Promise<any> }
*/
post = (data, { url = this.endpoint, ...rest } = {}) => {
const response = this.instance.post(url, data, { ...rest })
return response
}
}
import BaseService from './baseService'
export class AuthService extends BaseService {
/**
* Initializes Auth Service.
*/
constructor() {
super('/auth/local')
}
/**
* Logs Current user.
* @param { String } identifier - User's Identifier
* @param { String } password - User´s password.
* @return { Promise<String> } jwt access token.
*/
async login(identifier, password) {
const user = await this.post({ password, identifier }, { url: '/auth/local' })// when I call return cant find post of null
return user
}
}
export default AuthService
import axios from 'axios'
import { call, takeLatest } from 'redux-saga/effects'
import { fetchLogin } from './authReducer'
import AuthService from 'api/authService'
const authService = new AuthService()
export function* fetchLoginSaga(action) {
const response = yield call(authService.login, 'email', 'password')
console.log({ response })// don't print
}
export function* watcherSaga() {
yield takeLatest(fetchLogin.type, fetchLoginSaga)
}
解决方案
在幕后,redux-saga
将调用你的函数 .apply
,缺少对象的this
上下文,authService
仓库 issue 中的详细信息: https ://github.com/redux-saga/redux-saga/issues/27
你有两种方法可以解决这个问题:
call
将签名更改为yield call([auth, 'login'], "email", "password");
- 您可以改用
apply
效果 -yield apply(auth, auth.login, ["email", "password"]);
auth.login
或者您可以使用纯 JavaScript将父对象绑定到函数:
yield call(authService.login.bind(authService), 'email', 'password')
我建议使用正确的效果或效果签名来代替!
“context”/“fn”的文档可以在redux-saga
文档中找到:
https ://redux-saga.js.org/docs/api/#callcontext-fn-args
推荐阅读
- typescript - TypeScript:不可分配给 boolean 或 PromiseLike
- android - 在 Kotlin Android 中将文件作为公共上传到 S3
- django - Visual Studio 2017 Django 项目问题
- javascript - 您如何在任何网站上运行 Js 文件?
- components - InstallShield - 组件的条件
- regex - 如何在`StringCvt.scanString(RE.findcompiledComment)输入`中访问len和pos
- kotlin - 如何在 Kotlin 中将两个不同的类数据合并为一个
- php - yii2 单元测试不会在数据库中添加记录
- ios - UIScrollView 在屏幕结束后不滚动
- html - CSS不正确的元素高度