【问题标题】:Redux app business logic that doesn't affect the state?不影响状态的 Redux 应用业务逻辑?
【发布时间】:2016-10-16 11:42:40
【问题描述】:

我有一个使用 Oauth2“重定向流”来验证用户身份的应用程序,即用户被重定向到另一个网站进行登录,然后被重定向回我的网站。

文档和其他来源似乎都声称业务逻辑应该放在动作创建者或减速器中。但是我有一个login() 函数,它不会以任何方式更改状态,它所做的是将应用程序的当前状态保存为localStorage 中的普通对象,然后将用户重定向到授权服务器。当用户登录并被重定向回来时,状态被恢复(通过另一段代码)并作为初始状态提供给我的商店创建函数。

我的问题:login 函数的逻辑只是检索状态,但不会以任何方式更改它,因此它不属于减速器。它也不返回作为动作创建者定义的动作。我应该把它放在我的应用程序结构的什么位置?

拥有一个实际上不创建动作的动作创建者是否“可以”?我现在正在使用 redux-thunk 执行此操作(因为我需要 getState())并且它可以正常工作,但感觉不对,因为它实际上不是“动作创建者”,另一方面我也有一个 @ 987654325@ 函数确实返回一个动作,所以感觉他们应该住在同一个地方。我想这是一种极端情况,但不是真的,因为我可以想到很多理由以这种方式保存状态并将访问者重定向到其他站点(或者甚至只是保存状态而不重定向)。

PS。我知道有一些库可以自动将我的 redux 存储与 localStorage 同步,但这并不是问题的重点。

编辑:一些澄清:

来自Redux docs 关于业务逻辑的放置位置: 对于 reducer 或 action creator 中应该包含哪些逻辑,没有一个明确的答案。

继续阅读,很明显,我应该在两个地方放置业务逻辑,一个是 reducer,一个是 action creator。现在,由于我想做的事情不会影响状态,并且根据定义,reducer 会影响状态,所以我倾向于将此逻辑放入动作创建器中。

关于动作创建者的文档:动作创建者就是这样——创建动作的函数。将术语“动作”和“动作创建者”混为一谈很容易,因此请尽量使用正确的术语。 [...] 在 Redux 中,动作创建者只需返回一个动作

动作文档:动作是纯 JavaScript 对象。

我的登录示例的伪代码:

function login() {
    // retrieving and serializing the state, then:
    localStorage.set('my_app_id_state', my_serialized_state);
    window.location = url_to_authorization_service;
}

这段代码显然在动作创建者中没有位置,因为我没有返回动作,这是动作创建者的目的。但是我仍然需要检索状态,所以我也不能让它完全独立。

同样,问题是我应该将这段代码放在我的应用程序结构中的什么位置?

再一次,代码工作正常,一切都很好,所以我想这更像是一个学术问题,但它让我很烦恼,因为我在这里显然违反了 Redux 的基本规则。也许只是个例外?

【问题讨论】:

    标签: javascript redux redux-thunk


    【解决方案1】:

    这是一个很好的问题,让我意识到我做错了什么。所以希望这个答案至少对双方都有帮助:)

    以这个改编自Real World Redux example的例子为例:

    一个私有函数

    function oauth(url) {
     return (dispatch) => {
       dispatch({
        type: types.OAUTH_LOGIN,
        url
       });
     };
    }
    

    由动作创建者调用(返回一个函数)

    export function loginToApi(redirectUrl) {
      return (dispatch) => {
        return dispatch(oauth(redirectUrl))
      }
    }
    

    然后在组件中依次调用该操作,如下所示:

    login() {
     return this.props.dispatch(loginToApi());
    }
    

    因此,回答您的问题的一种方法是将您的业务逻辑放在私有方法中,然后由操作创建者调用。

    可能有一种更优雅的方式,但这就是我在上面提到的文档中的做法。

    关于将状态存储在本地存储中的登录逻辑:我认为您不需要这个。 Redux 商店正在为您管理状态。

    【讨论】:

    • 您好,感谢您抽出宝贵时间回答。如果我的问题令人困惑,我很抱歉,我试图举一个例子,我需要在我的应用程序中做一些不影响其状态的事情。来自 Redux 文档:“操作是将数据从应用程序发送到商店的信息负载。[...] 操作是纯 JavaScript 对象。操作必须具有类型属性...”在您的示例中,您没有返回普通对象,我也没有在我的登录功能中这样做。因此,我们都没有遵循规范来确定一个动作应该是什么,这就是这里的问题:)
    • 我现在编辑了我的问题,也许现在我要问的更清楚了。
    • 哈,好点子!让我编辑我的答案。同时,你有没有看到这个github.com/reactjs/redux/blob/…我认为你的解决方案在那里
    • 谢谢,但我不认为我变得更聪明了。异步动作创建者实际上不返回普通对象,所以我想也许我应该将文档作为“纯”redux 应用程序的规则阅读,即没有任何中间件,但这听起来很奇怪,因为中间件是 Redux 最强大的功能之一(很少根本不需要任何中间件的情况)。最后,异步动作创建者正在调用其他动作创建者,并最终有效地完成了它应该做的事情 - 调度影响状态的普通对象动作。
    • 没问题,谢谢讨论。我在推特上发了 Dan Abramov,希望他能看到。但是,是的,我现在要继续违反规则。
    【解决方案2】:

    Dan Abramov 在 Twitter 上回复,我将得出结论,这是文档中概述的规则的例外。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-21
      • 2015-11-10
      • 2023-03-30
      • 1970-01-01
      • 1970-01-01
      • 2018-06-06
      相关资源
      最近更新 更多