简体   繁体   English

对“this”的引用是由 redux-saga 调用调用的 function 中的 null

[英]Reference to “this” is null in function called by redux-saga call

I'm learning redux-saga and I'm trying to integrate it into a project that uses an API that is generated with openapi-generator which produces output like the following:我正在学习redux-saga ,我正在尝试将其集成到一个使用 API 的项目中,该项目是由 openapi-generator 生成的,它产生 output,如下所示:

async loginUser(body: Login): Promise<LoginResponse> {
    debugger;
    const response = await this.loginUserRaw({ body: body });
    return await response.value();
}

And loginUserRaw is a function that performs the actual login.loginUserRaw是执行实际登录的 function。 Then, I have the following saga:然后,我有以下传奇:

function* login(action:Login) {
    try{
        const response = yield call(User.loginUser, action);
        yield result(LOGIN_SUCCESS, response)
    }catch(e){
        yield result(LOGIN_FAILURE, e)
    }
}

When this runs, I get an error in my API method's await this.loginUserRaw({ body: body });当它运行时,我的 API 方法的await this.loginUserRaw({ body: body });出现错误。 line:线:

TypeError: Cannot read property 'loginUserRaw' of null

I debug it and see that this is null.我调试了一下,发现this是 null。 When I bind the function explicitly in the saga:当我在传奇中明确绑定 function 时:

const response = yield call(User.loginUser.bind(User), action);

It works, but I don't wanna bind it every time I call a function.它有效,但我不想每次调用 function 时都绑定它。 How can I get saga to work without explicitly binding the function?如何在不显式绑定 function 的情况下让 saga 工作? (I can't change the generated code and remove this either) (我也无法更改生成的代码并将this删除)

Context in Javascript is dynamic based on the way you've written your code Javascript 中的上下文是动态的,取决于您编写代码的方式

const loginUser = User.loginUser
loginUser() // context lost, because there is no longer `User.` in front of it

Same applies when you pass a function as an parameter.当您将 function 作为参数传递时,同样适用。 This means that you have to provide the call effect context in some way.这意味着您必须以某种方式提供call效果上下文。 The bind method is one option, however the effect itself supports multiple ways of providing context. bind方法是一种选择,但效果本身支持多种提供上下文的方式。 You can find them in the official docs https://redux-saga.js.org/docs/api/#callcontext-fn-args , here is the short version of it:您可以在官方文档https://redux-saga.js.org/docs/api/#callcontext-fn-args中找到它们,这是它的简短版本:

Possible ways to pass context:传递上下文的可能方法:

call([context, fn], ...args)
call([context, fnName], ...args)
call({context, fn}, ...args)

So for example you can do the following:因此,例如,您可以执行以下操作:

const response = yield call([User, User.loginUser], action);

loginUser is being used as if it's a static method. loginUser被用作 static 方法。

You'll need to instantiate the class prior to using it, like this:您需要在使用 class 之前对其进行实例化,如下所示:

function* login(action:Login) {
    try{
        const user = new User()
        const response = yield call(user.loginUser, action);
        yield result(LOGIN_SUCCESS, response)
    }catch(e){
        yield result(LOGIN_FAILURE, e)
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM