gpt4 book ai didi

javascript - React类组件方法: is my code imperative?

转载 作者:行者123 更新时间:2023-12-01 02:01:20 24 4
gpt4 key购买 nike

我对 react 以及函数式、命令式、声明式等术语都是新手。我发现纯函数很容易测试。我自学使用 Javascript 进行编程。到目前为止,它正在工作,但我的目标是学习编写干净且可维护的代码。我的问题是下面的方法 addProductToSaleList 很糟糕且无法测试,因为它是命令式的?以及我该如何做不同的事情。

class SaleComponent extends React.Component {

addProductToSaleList = (values, dispatch, props) => {
//filter product from productList
const productFound = props.productList.filter(product => {
if (values.productCode === product.code.toString()) {
return product
}
return undefined
})[0]

if (productFound) {

// filter sale list to check if there is already product in the list.
const detailFound = props.saleItem.details.filter(detail => {
if (productFound.name === detail.product) {
return detail
}
return undefined
})[0]

// if it is exist just increment the qty
if (detailFound) {
const { sub_total, ...rest } = detailFound
props.dispatcher('UPDATE_SALEDETAIL_ASYNC', {
...rest,
qty: parseInt(detailFound.qty, 10) + 1
})

// if it is not exist add new one
} else {
props.dispatcher('ADD_SALEDETAIL_ASYNC', {
product: productFound.id,
price: productFound.price,
qty: 1
})
}
} else {

alert('The product code you add is not exist in product list');
}
}
render() {
// Render saleList
}
}

最佳答案

我相信这个问题应该去Code Review ,但我会尝试一下。部分代码可以改进

const productFound = props.productList.filter(product => {
if (values.productCode === product.code.toString()) {
return product
}
return undefined
})[0]

首先,filter函数接收一个回调,并且对于每个项目都会执行该回调。如果回调返回一个解释为 true 的值,它将返回该函数将构建的新数组中的项目。否则,它将跳过该项目。假设您试图在代码中查找一项,您可以使用函数 find这将直接返回该元素(不需要 [0]),或者如果未找到该项目,则返回未定义的元素。所以你的代码可以重写为

const productFound = props.productList.find(product => values.productCode === product.code.toString());

注意:不支持 IE。

然后,如果未找到该值,您可以发出警报并执行 early return 。 (您可能还希望以不同的方式处理错误,使用比普通警报更好的格式)。

代码看起来像

if (!productFound) {
alert('The product code you add is not exist in product list');
return;
}
// rest of the function

为了查找详细信息,您也可以使用find方法

const detailFound = props.saleItem.details.find(detail => productFound.name === detail.product);

然后调用其余代码

// if it is exist just increment the qty
if (detailFound) {
const { sub_total, ...rest } = detailFound
props.dispatcher('UPDATE_SALEDETAIL_ASYNC', {
...rest,
qty: parseInt(detailFound.qty, 10) + 1
})

// if it is not exist add new one
} else {
props.dispatcher('ADD_SALEDETAIL_ASYNC', {
product: productFound.id,
price: productFound.price,
qty: 1
})
}

另一项改进:

您正在接收调度函数作为参数,但您没有使用它。所以你可以从函数的声明中删除它

(values, props) => { ... } 

你可以将最后一部分分成两个不同的函数,例如

const getAction = details => `${detailFound ? 'UPDATE' : 'ADD'}_SALEDETAIL_ASYNC`;

const getObject = (details, productFound) => {
if (!details) {
return {
product: productFound.id,
price: productFound.price,
qty: 1
};
}
const { sub_total, ...rest } = detailFound;
return {
...rest,
qty: parseInt(detailFound.qty, 10) + 1
};
}

然后调用

props.dispatcher(getAction(details), getObject(details, productFound));

最终结果如下

addProductToSaleList = (values, props) => {
//filter product from productList
const productFound = props.productList.find(product => values.productCode === product.code.toString());

if (!productFound) {
alert('The product code you add is not exist in product list');
return;
}

// filter sale list to check if there is already product in the list.
const detailFound = props.saleItem.details.find(detail => productFound.name === detail.product);

const getAction = details => `${details ? 'UPDATE' : 'ADD'}_SALEDETAIL_ASYNC`;

const getObject = (details, productFound) => {
if (!details) {
return {
product: productFound.id,
price: productFound.price,
qty: 1
};
}
const { sub_total, ...rest } = details;
return {
...rest,
qty: parseInt(details.qty, 10) + 1
};
}

props.dispatcher(getAction(details), getObject(details, productFound));
}

my question is the method addProductToSaleList below is bad and untestable because it is imperative

您的代码是可测试的,没有外部依赖项。因此,您可以传递模拟值和 Prop ,并向其添加单元测试。这意味着,传递一个假的值和属性(它们只是普通的 js 对象)并对其进行断言。

例如:

您可以模拟 dispatcher 函数,并给出 ProductList 和 saleItem.details 中的假值,您可以查看是否使用正确的方式调用了 dispatcher值(value)观。您应该测试不同的组合

模拟 alert 函数(同样,我会使用另一种 UI 方法)并验证它是否被调用,并且没有调用其他代码(断言您的假 dispatcher 是不叫)。像这样的事情:

   let actionToAssert;
let objectToAssert;
let values = { productCode: 'somecode' };
let props = {
productList: // your item listm with id and price, name, etc,
saleItem: {
details: // your details array here
}
dispatcher: (action, newObject) => {
actionToAssert = action;
objectToAssert = newObject;
}
}
addProductToSaleList(values, props); // make here assertions over actionToAssert and objectToAssert

关于javascript - React类组件方法: is my code imperative?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50545177/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com