将数据从redux存储转换为简单函数的最佳实践方法是什么?

时间:2018-11-01 01:03:31

标签: reactjs react-native redux redux-thunk

说我有一个名为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。

2 个答案:

答案 0 :(得分: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 });

    // ...
}

答案 1 :(得分:0)

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

首先,计算应该是一个单独的函数,该函数将所需的所有数据作为参数(这样,您还可以轻松对其进行单元测试),并且不在乎是否在React应用程序中使用了它,或者您是否在使用Redux之类的。如果您认为它会以相同的参数多次调用,那么您也可以阅读称为“记忆”的概念,但是我想大多数情况下,记忆应该发生在此功能之外。

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

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