Search code examples
javascriptreactjsfunctionnext.jsaddition

Add Numbers in ReactJS without button


Seems like an easy task to add few number but I am not getting any luck without usage of explicit button to add numbers.

  // Defining useState

  const [ totalCount, setTotalCount ] = useState(0)

  // User Can change count of fruits by increment or decrement operator

  const addNum = (apples,mango,orange) => {
    setTotalCount(parseInt(apples) + parseInt(mango) + parseInt(orange))
  }

  console.log("Total Number of Fruits", totalCount)

Desired Answer : Some number between 0 and 3

Answer getting : NaN


Solution

  • The component will track the quantities of individual items. The sum of the items is derived state and should NOT be saved as state of its own. Instead compute the sum on-the-fly -

    function App({ items = [] }) {
      const [counts, setCounts] = React.useState(new Map)
      const update = (key, amount) => event =>
        setCounts(m => new Map(m).set(key, (m.get(key) || 0) + amount))
      return <div>
        {items.map(item =>
          <Item key={item} item={item} count={counts.get(item) || 0} update={update} />
        )}
        total: {[...counts.values()].reduce((a,b) => a + b, 0)}
      </div>
    }
    
    function Item({ item, update, count }) {
      return <div>
        <button type="button" onClick={update(item, -1)} children="➖" />
        {item}: {count}
        <button type="button" onClick={update(item, 1)} children="➕" />
      </div>
    }
    
    ReactDOM.render(<App items={["🫐", "🍑", "🥝"]}/>, document.body)
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.0/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.0/umd/react-dom.production.min.js"></script>

    Decomposition of a generic update and sum function allow you to keep the component logic simplified and allow these functions to be reused in other areas of your program -

    function updateCount(map, key, amount) {
      return new Map(map).set(key, (map.get(key) || 0) + amount)
    }
    
    function sum(iter) {
      return [...iter].reduce((a,b) => a + b, 0)
    }
    
    function App({ items = [] }) {
      const [counts, setCounts] = React.useState(new Map)
      const update = React.useCallback((key, amount) => event =>
        setCounts(m => updateCount(m, key, amount)),
        []
      )
      return <div>
        {items.map(item =>
          <Item key={item} item={item} count={counts.get(item) || 0} update={update} />
        )}
        total: {sum(count.values())}
      </div>
    }