When asked to increment / decrement a particular value I usually create specific functions to handle this functionality. Like this:
const increaseQuantity = index => {
const currentItems = [...stock];
currentItems[index].quantity += 1;
setStock(currentItems);
};
const decreaseQuantity = index => {
const currentItems = [...stock];
if (currentItems[index].quantity > 1) {
currentItems[index].quantity -= 1;
setStock(currentItems);
}
};
I like this approach because it clearly separates each action. Also, it only takes one single argument which keeps things simple.
But I can also create a single function, that does both things (increment or decrement), but it uses an additional parameter action
as well as logic to perform the update:
const manageQuantity = (index, action) => {
const currentItems = [...stock];
if (action === "increase") {
currentItems[index].quantity += 1;
setStock(currentItems);
}
if (currentItems[index].quantity > 1 && action === "decrease") {
currentItems[index].quantity -= 1;
setStock(currentItems);
}
};
I feel that the second pattern (single function) is more prone to error. Mainly because the the second argument is a (string).
Which is considered best practice and also follows some established (or well known) design pattern? Also, is one pattern more performant than the other?
Full functioning example below:
const availableItems = [
{
name: "iPod Nano",
capacity: "4GB",
quantity: 3
},
{
name: "iPod Classic",
capacity: "30GB",
quantity: 2
},
{
name: "iPod Mini",
capacity: "4GB",
quantity: 5
}
];
function FirstApp() {
const [stock, setStock] = React.useState(availableItems);
const increaseQuantity = index => {
const currentItems = [...stock];
currentItems[index].quantity += 1;
setStock(currentItems);
};
const decreaseQuantity = index => {
const currentItems = [...stock];
if (currentItems[index].quantity > 1) {
currentItems[index].quantity -= 1;
setStock(currentItems);
}
};
return (
<div className="app">
<h2>FirstApp</h2>
{JSON.stringify(stock)}
<hr />
{stock.map((item, i) => (
<div key={item.name}>
{item.name} | <button onClick={() => increaseQuantity(i)}>+</button>
<button onClick={() => decreaseQuantity(i)}>-</button>
</div>
))}
</div>
);
}
function SecondApp () {
const [stock, setStock] = React.useState(availableItems);
const increaseQuantity = index => {
const currentItems = [...stock];
currentItems[index].quantity += 1;
setStock(currentItems);
};
const decreaseQuantity = index => {
const currentItems = [...stock];
if (currentItems[index].quantity > 1) {
currentItems[index].quantity -= 1;
setStock(currentItems);
}
};
const manageQuantity = (index, action) => {
const currentItems = [...stock];
if (action === "increase") {
currentItems[index].quantity += 1;
setStock(currentItems);
}
if (currentItems[index].quantity > 1 && action === "decrease") {
currentItems[index].quantity -= 1;
setStock(currentItems);
}
};
return (
<div className="app">
<h2>SecondApp</h2>
{JSON.stringify(stock)}
<hr />
{stock.map((item, i) => (
<div key={item.name}>
{item.name} |{" "}
<button onClick={() => manageQuantity(i, "increase")}>+</button>
<button onClick={() => manageQuantity(i, "decrease")}>-</button>
</div>
))}
</div>
);
}
function App() {
return (
<React.Fragment>
<FirstApp />
<SecondApp />
</React.Fragment>
)
}
ReactDOM.render(<App/>, document.getElementById('root'));
.app {
border: 2px solid grey;
padding: 10px;
margin: 10px;
}
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>