说我有一个名为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。
答案 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用作具有原始值的缓存,如果我需要从中派生值,则可以使用备注选择器。