-1

I have have useState hook where I have array of 0's as follows const [binary, setBinary] = useState([0, 0, 0, 0, 0, 0, 0, 0]); Then I have function called isToggled where I set the toggle to true and variable called bin that gets the binary value which is then sliced and concat and then set with the hook. I have so far it working a way that all the 0's will turn to 1's but won't go to zero when the checkbox is unchecked. enter image description here

Then in the input fields onChange it is used as follows

<input type="checkbox" onChange={(e, b) => isToggled(0, b)} />
        <input type="checkbox" onChange={(e, b) => isToggled(1, b)} />
        <input type="checkbox" onChange={(e, b) => isToggled(2, b)} />
        <input type="checkbox" onChange={(e, b) => isToggled(3, b)} />
        <input type="checkbox" onChange={(e, b) => isToggled(4, b)} />
        <input type="checkbox" onChange={(e, b) => isToggled(5, b)} />
        <input type="checkbox" onChange={(e, b) => isToggled(6, b)} />
        <input type="checkbox" onChange={(e, b) => isToggled(7, b)} />

And in the text input field

<input
   name="binary"
   type="text"
   value={binary}
   onChange={binary.join("")}
/>

Whole code is as follows.

import React, { useState } from "react";
import "./App.css";

function Binary() {
  const [binary, setBinary] = useState([0, 0, 0, 0, 0, 0, 0, 0]);
  const [toggle, setToggle] = useState(false);
  const [decimal, setDecimal] = useState(0);
  const isToggled = (form) => {
    setToggle(true);
    let bin = binary
      .slice(0, form)
      .concat([toggle ? 1 : 0])
      .concat(binary.slice(form + 1));
    setBinary(bin);
  };
  const showDecimal = (e) => {
    setDecimal("" + parseInt(binary.join(""), 2));
    e.preventDefault();
  };
  return (
    <div className="App">
      <header className="App-header">
        <form className={"form"}>
          <div>
            <input type="checkbox" onChange={(e, b) => isToggled(0, b)} />
            <input type="checkbox" onChange={(e, b) => isToggled(1, b)} />
            <input type="checkbox" onChange={(e, b) => isToggled(2, b)} />
            <input type="checkbox" onChange={(e, b) => isToggled(3, b)} />
            <input type="checkbox" onChange={(e, b) => isToggled(4, b)} />
            <input type="checkbox" onChange={(e, b) => isToggled(5, b)} />
            <input type="checkbox" onChange={(e, b) => isToggled(6, b)} />
            <input type="checkbox" onChange={(e, b) => isToggled(7, b)} />
          </div>
          <div>
            <input
              name="binary"
              type="text"
              value={binary}
              onChange={binary.join("")}
            />
          </div>
          <div>
            <button onClick={showDecimal}>Convert</button>
          </div>
          <div>
            <input type="text" value={decimal} />
          </div>
        </form>
      </header>
    </div>
  );
}

export default Binary;
Jukka Koivu
  • 63
  • 1
  • 10

2 Answers2

1

If you insist on this structure, I refactored your code a bit. I got rid of the "toggle" variable because you can just use the event from the input field. This means, that your new toggle is going to be the 'checked' state on the input itself which is either true or false. I tested it and it works.

import React, { useState } from "react";

function Binary() {
    const [binary, setBinary] = useState([0, 0, 0, 0, 0, 0, 0, 0]);
    const [decimal, setDecimal] = useState(0);
    const isToggled = (position, value) => {
        let bin = binary
            .slice(0, position)
            .concat([value ? 1 : 0])
            .concat(binary.slice(position + 1));
        console.log(bin)
        setBinary(bin);
    };
    const showDecimal = (e) => {
        setDecimal("" + parseInt(binary.join(""), 2));
        e.preventDefault();
    };
    return (
        <div className="App">
            <header className="App-header">
                <form className={"form"}>
                    <div>
                        <input type="checkbox" onChange={(e => isToggled(0, e.target.checked))} />
                        <input type="checkbox" onChange={(e => isToggled(1, e.target.checked))} />
                        <input type="checkbox" onChange={(e => isToggled(2, e.target.checked))} />
                        <input type="checkbox" onChange={(e => isToggled(3, e.target.checked))} />
                        <input type="checkbox" onChange={(e => isToggled(4, e.target.checked))} />
                        <input type="checkbox" onChange={(e => isToggled(5, e.target.checked))} />
                        <input type="checkbox" onChange={(e => isToggled(6, e.target.checked))} />
                        <input type="checkbox" onChange={(e => isToggled(7, e.target.checked))} />
                    </div>
                    <div>
                        <input
                            name="binary"
                            type="text"
                            value={binary}
                            readOnly
                        />
                    </div>
                    <div>
                        <button onClick={showDecimal}>Convert</button>
                    </div>
                    <div>
                        <input type="text" value={decimal} readOnly />
                    </div>
                </form>
            </header>
        </div>
    );
}

export default Binary;
voxtool
  • 345
  • 4
  • 11
0

First of all,

        <input type="checkbox" onChange={(e, b) => isToggled(0, b)} />
        <input type="checkbox" onChange={(e, b) => isToggled(1, b)} />
        <input type="checkbox" onChange={(e, b) => isToggled(2, b)} />
        <input type="checkbox" onChange={(e, b) => isToggled(3, b)} />
        <input type="checkbox" onChange={(e, b) => isToggled(4, b)} />
        <input type="checkbox" onChange={(e, b) => isToggled(5, b)} />
        <input type="checkbox" onChange={(e, b) => isToggled(6, b)} />
        <input type="checkbox" onChange={(e, b) => isToggled(7, b)} />

this is a very bad design. Try rendering like this:

{binary.map((bin,index) => <input key={index} type="checkbox" onChange={(e, b) => isToggled(index, b)} />)}

Since your rendered element does not depend on your binary state, your update doesn't reflect on the component, since the state changes but there is nothing different with the rendered jsx element

Note: Giving key={index} has some problems in some cases, which you can read more here

Sinan Yaman
  • 5,714
  • 2
  • 15
  • 35