0

I am using an increment (count) for not to click the period (.) second time. So once the period is clicked then second time it skips. I used the example from Incrementing state value by one using React, but the count is not incrementing.

const InitVal = ({ strValue, handleClick }) => (
   <div>
     {strValue.map((item) => (
        <button onClick={() => handleClick(item.key)}>{item.key}</button>
     ))}
  </div>
);
class App extends React.Component {
  constructor(props) {
    super(props);
      this.state = {strValue: [{ key: '7' },{ key: '8' },{ key: '9' },{ key: '4' },{ key: '5' },{ key: '6' },{ key: '1' },{ key: '2' },{ key: '3' },{ key: '0' },{key: '.'}],value: '0',count: 0,};
      this.handleClick = this.handleClick.bind(this);
      }

     handleClick(key) {
         const { value } = this.state;
         const { count } = this.state;
         const digNprd = /[0-9.]/ 
         if (value.charAt(0) === "0") {
            this.setState({ value: `${key}` })  
         } else if (digNprd.test(key)) {
             this.setState((u) => {
                  if (key === '.') {                 
                      if (u.count < 1) {
                        count: u.count + 1   
                      } else {
                          key = ''
                      }
                   }
               return { value: `${value}${key}` }
             })   
          }
      }
   render() {
      return (
         <div><br /><InitVal strValue={this.state.strValue} handleClick={this.handleClick} /> <br /> <div>value: &nbsp;&nbsp;{this.state.value}</div><br />
           <div>count: &nbsp;&nbsp;{this.state.count}</div>
         </div>
   );
  }
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.0/umd/react-dom.production.min.js"></script>

<div id='root'></div>
user6642297
  • 395
  • 3
  • 19

2 Answers2

1

You are returning the value, and the key but you never return the new count value. So the state is not updating that value

try this:

handleClick(key) {
        const { value } = this.state;
        let { count } = this.state;
        const digNprd = /[0-9.]/ 
        if (value.charAt(0) === "0") {
           this.setState({ value: `${key}` })  
        } else if (digNprd.test(key)) {
            this.setState((u) => {
                 if (key === '.') {                 
                    if (u.count < 1) {
                        count = u.count + 1;
                      } else {
                        key = "";
                      }
                  }
              return { value: `${value}${key}`, count }
            })   
         }
     }
  • @user6642297 i updated the code, give that a try – Joseph Stacey Feb 03 '21 at 22:43
  • @user6642297 the above answer is correct and working without any error, the problem is you are not returning updated value of count which in turn never updates count in state. Here `{ value: `${value}${key}`, count }` is equivalent to `{ value: `${value}${key}`, count: count }` more about this here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer – Hemant Feb 04 '21 at 09:40
  • @user6642297 check my answer – Hemant Feb 04 '21 at 16:48
1

Based on the code available in OP i am updating a working snippet for you as i am not sure why the updated solution is not working for you. With the help of this you can compare and find out where the issue lies.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
    </head>
    <body>
        <div id="root"></div>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.0/umd/react.production.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.0/umd/react-dom.production.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.24.0/babel.js"></script>
        <script type="text/babel">
            const InitVal = ({ strValue, handleClick }) => (
                <div>
                    {strValue.map((item) => (
                        <button onClick={() => handleClick(item.key)}>
                            {item.key}
                        </button>
                    ))}
                </div>
            );
            class App extends React.Component {
                constructor(props) {
                    super(props);
                    this.state = {
                        strValue: [
                            { key: "7" },
                            { key: "8" },
                            { key: "9" },
                            { key: "4" },
                            { key: "5" },
                            { key: "6" },
                            { key: "1" },
                            { key: "2" },
                            { key: "3" },
                            { key: "0" },
                            { key: "." },
                        ],
                        value: "0",
                        count: 0,
                    };
                    this.handleClick = this.handleClick.bind(this);
                }

                handleClick(key) {
                    const { count, value } = this.state;
                    const digNprd = /[0-9.]/;
                    if (value.charAt(0) === "0") {
                      this.setState((u) => {
                           let count = u.count
                           if (key === '.') {
                               if (count < 1) {
                                   count = count + 1 
                               } else {
                                   key = ''
                               }
                            }
                            return { value: `${key}`, count }
                    }); 
                    } else if (digNprd.test(key)) {
                        this.setState((u) => {
                            let count = u.count;
                            if (key === ".") {
                                if (u.count < 1) {
                                    count= u.count + 1;
                                } else {
                                    key = "";
                                }
                            }
                            return { value: `${value}${key}`, count };
                        });
                    }
                }
                render() {
                    return (
                        <div>
                            <br />
                            <InitVal
                                strValue={this.state.strValue}
                                handleClick={this.handleClick}
                            />{" "}
                            <br />{" "}
                            <div>value: &nbsp;&nbsp;{this.state.value}</div>
                            <br />
                            <div>count: &nbsp;&nbsp;{this.state.count}</div>
                        </div>
                    );
                }
            }
            ReactDOM.render(<App />, document.getElementById("root"));
        </script>
    </body>
</html>

For explanation you can refer to joseph's answer and my comment on that answer.

user6642297
  • 395
  • 3
  • 19
Hemant
  • 1,127
  • 1
  • 10
  • 18
  • Thank you. It is working, but there is one glitch and I will fix it. If we put first two periods (.) keys then it prints two periods, instead of skipping the second period. – user6642297 Feb 04 '21 at 18:57
  • 1
    I fixed the second period (.) problem. Check if (value.charAt(0) === "0") { this.setState((u) => { let count = u.count if (key === '.') { if (count < 1) { count = count + 1 } else { key = '' } } return { value: `${key}`, count } }); – user6642297 Feb 05 '21 at 01:57
  • Glad, you got everything in place. Cheers! – Hemant Feb 05 '21 at 05:25