Skip to main content
fix minor bug
Source Link
Juan Marco
  • 153
  • 1
  • 8

Pattern usage for increment / decrement React (Hooks)

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={() => decreaseQuantity(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>
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>

Pattern usage for increment / decrement

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={() => decreaseQuantity(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>

Pattern usage for increment / decrement React (Hooks)

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>
Source Link
Juan Marco
  • 153
  • 1
  • 8

Pattern usage for increment / decrement

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={() => decreaseQuantity(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>