【问题标题】:What is the best practice approach to getting data from the redux store into a simple function?从 redux 存储中获取数据到简单函数的最佳实践方法是什么?
【发布时间】:2018-11-01 01:03:30
【问题描述】:

假设我有一个名为calculateFees 的函数,它需要从后端发送一些数据,例如consultingFee。它看起来像:

const calculateFees = itemPrice => itemPrice * [consultingFee]

[consultingFee] 是一个占位符,因为我不确定如何从 redux 商店获取它。还可以说calculateFees 要复杂得多,它有大约 10 多种费用类型,并被数十个组件使用。我能想到的选项是:

1) 传入连接到 redux 状态的调用它的类的所有费用。

(例如calculateFees(itemPrice, feeOne, feeTwo, FeeThree, ...)

2) 复制每个连接到 redux 状态的类中的代码。

3) 导出整个存储(或其中的一部分),以便calculateFees 函数可以通过导入访问数据。

4) 不确定这是否可能,但创建一个具有静态方法的类,并将其连接到 redux 存储。然后使用MyCompanyFees.calculateFees等。

5) 创建一个仅将数据拉出状态的 thunk,并返回计算的费用。使用它似乎不正确,因为它不是异步的,也不会更新状态树。

我想获得一些关于最佳实践方法的指导/建议,因为我不喜欢 1、2 或 3。

【问题讨论】:

    标签: reactjs react-native redux redux-thunk


    【解决方案1】:

    一个简单的计算/实用函数不应该知道它的数据来自哪里,而应该只接受它作为参数:

    const calculateFees = (itemPrice, consultingFee) => itemPrice * consultingFee
    

    如果数据来自存储,则应在选择器中调用calculateFees

    选择器:

    const getCalculatedFees = (state, { itemId }) => {
        const itemPrice = state.items[itemId].price;
        const consultingFee = state.consultingFee;
    
        return calculateFees(itemPrice, consultingFee);
    }
    

    然后选择器可以被组件或与动作相关的函数(如 thunk 和 sagas)使用。

    组件:

    connect(
        state => ({
            calculatedFees: getCalculatedFees(state)
        })
    )(MyComponent)
    

    重击:

    const myAction = itemId => (dispatch, getState) => {
        const calculatedFee = getCalculatedFees(getState(), { itemId });
    
        // do stuff...
        dispatch(doSomethingElse(calculatedFee));
    }
    

    传奇:

    function* mySaga({ itemId }) {
        const calculatedFee = yield select(getCalculatedFees, { itemId });
    
        // ...
    }
    

    【讨论】:

      【解决方案2】:

      我想说这在很大程度上取决于特定的用例,例如这些值(即计算函数的输入)可以改变的频率(是购物车之类的东西还是更像是生成的报告之类的东西,当您获取数据一次,仅此而已),并且如果它只是每个视图的一个计算或多个具有不同输入的计算(例如,您必须计算表格中每一行的费用)。

      首先,计算应该是一个单独的函数,它获取它需要的所有数据作为参数(这样你也可以轻松地对其进行单元测试)并且不关心它是在 React 应用程序中使用还是你正在使用Redux 什么的。如果您认为它会使用相同的参数被多次调用,您也可以阅读名为 memoization 的概念,但我想在大多数情况下,memoization 应该发生在此函数之外。

      现在,假设您的商店中已经拥有其余数据(您提到的 consultingFee 占位符),并且希望在从后端获得响应后获得计算值。在这种情况下,您可以从存储中提取值,如 bsapaka 的答案所示,并将计算的值放入 redux 存储中,您可以在需要的地方访问它。如果您发出一次请求,显示计算值就足够了,就是这样,您知道如果您需要再次计算它,您将有不同的输入值并且必须再次调用后端并且您不需要缓存结果,尽管我认为如果是这种情况,您根本不应该将计算出的值存储在您的商店中。

      您还可以在 mapStateToProps 函数中进一步使用选择器,reselect 库对此很有用(请务必阅读自述文件的“跨多个组件实例共享选择器”部分)。这样,您就拥有了调度操作的组件,该操作从后端获取您需要的数据并将其放入 redux 存储中。在 mapStateToProps 中,您使用 memoized 选择器收集它需要的所有数据并计算结果,除非输入(因此在这种情况下来自 redux 存储的相关值)发生变化,否则不会重新计算结果。我更喜欢这种方法,因为它减少了 redux 中的副作用并且对我来说更具声明性,但我也更喜欢将 redux 用作具有原始值的缓存,如果我需要从中派生值,我会使用记忆选择器。

      【讨论】:

        猜你喜欢
        • 2011-12-03
        • 1970-01-01
        • 1970-01-01
        • 2023-02-06
        • 1970-01-01
        • 1970-01-01
        • 2010-09-25
        • 2016-08-27
        • 2011-02-14
        相关资源
        最近更新 更多