Search code examples
javascriptreactjsinputuse-state

how to switch between inputs in converter app in react?


I built a celsius(as input) to fahrenheit(as output) conveter with react But
I want to switch between celsius and fahrenheit as input and output
I mean when I click on fahrenheit it turn to input and use can edit it an type init and see
celsius as result(as output) and viceversa
What to do to switch between input and output?

import { useState } = React;
function App() {
    // Use State
    const [celsius_value, set_celsius_value] = useState("");
    const [fahrenheit_value, set_fahrenheit_value] = useState("");

    // state functions
    const celsius_to_fahrenheit_converter = (e) => {
        const celsius_value_input = Number(e.target.value);
        set_celsius_value(celsius_value_input);
        // convert value
        set_fahrenheit_value((celsius_value_input * 9) / 5 + 32);
    };

    const fahrenheit_to_celsius_converter = (e) => {
        const fahrenheit_value_input = Number(e.target.value);
        set_fahrenheit_value(fahrenheit_value_input);
        // Convet value
        set_celsius_value(((fahrenheit_value_input - 32) * 5) / 9);
    };
  
    return (
        <div className="container">
            {/* Celsius */}
            <div className="celsius-container">
                <label htmlFor="celsius-input">celsius</label>
                <input
                    type="number"
                    name="celsius"
                    id="celsius-input"
                    value={celsius_value}
                    onChange={(e) => {
                        celsius_to_fahrenheit_converter(e);
                    }}
                />
            </div>
            {/* fahrenheit  */}
            <div className="fahrenheit -container">
                <label htmlFor="fahrenheit -input">fahrenheit </label>
                <input
                    type="number"
                    name="fahrenheit "
                    id="fahrenheit-input"
                    value={fahrenheit_value}
                    onChange={(e) => {
                        fahrenheit_to_celsius_converter(e);
                    }}
                />
            </div>
        </div>
    );
}
ReactDOM.render(<App />, document.getElementById("root"));
.container{
  border:1px solid green;
  width:30%;
  height:30vh;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: center;
}

.container div{
  display: flex;
  flex-direction: column;
}

label{
  font-size:20px;
  text-transform: uppercase;
  font-family: monospace;
}

#celsius-input,#fahrenheit-input{
  padding:10px 20px;
  text-align: center;
  outline:none;
}
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<div id="root"></div>


Solution

  • You can use the same onChange handler but with a condition based on the current focused input:

    const useState = React.useState
    
    function App() {
        // Use State
        const [celsius_value, set_celsius_value] = useState(0);
        const [fahrenheit_value, set_fahrenheit_value] = useState(0);
        const [selected, setSelected] = useState("")
    
        // state functions
        const handleConversion = (e) => {
        if(selected === "celsius"){
            set_celsius_value(e.target.value);
            set_fahrenheit_value(((e.target.value) * (9 / 5) + 32).toFixed(1));
            } else {
             set_fahrenheit_value(e.target.value);
             set_celsius_value(((e.target.value - 32) * (5 / 9)).toFixed(1));
            // convert value
    }
        };
    
        return (
            <div className="container">
                {/* Celsius */}
                <div className="celsius-container">
                    <label htmlFor="celsius-input">celsius</label>
                    <input
                        type="number"
                        name="celsius"
                        id="celsius-input"
                        value={celsius_value}
                        onFocus={(e) => setSelected("celsius")}
                        onChange={handleConversion}
                    />
                </div>
                {/* fahrenheit  */}
                <div className="fahrenheit -container">
                    <label htmlFor="fahrenheit -input">fahrenheit </label>
                    <input
                        type="number"
                        name="fahrenheit "
                        id="fahrenheit-input"
                        value={fahrenheit_value}
                        onFocus={(e) => setSelected("farenheit")}
                        onChange={handleConversion}
                    />
                </div>
            </div>
        );
    }
    
    ReactDOM.render(<App />, root)
    .container{
      border:1px solid green;
      width:30%;
      height:30vh;
      display: flex;
      flex-direction: column;
      justify-content: space-between;
      align-items: center;
    }
    
    .container div{
      display: flex;
      flex-direction: column;
    }
    
    label{
      font-size:20px;
      text-transform: uppercase;
      font-family: monospace;
    }
    
    #celsius-input,#fahrenheit-input{
      padding:10px 20px;
      text-align: center;
      outline:none;
    }
    <div id="root"></div>
    
    <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>