import React, { useReducer } from "react"; // Define the state type interface TemperatureState { celsius: string; fahrenheit: string; } // Define the action type type TemperatureAction = | { type: "SET_CELSIUS"; payload: string; formattedFahrenheit: string } | { type: "SET_FAHRENHEIT"; payload: string; formattedCelsius: string }; // Initial state const initialState: TemperatureState = { celsius: "", fahrenheit: "" }; // Reducer function using the defined types const temperatureReducer = ( state: TemperatureState, action: TemperatureAction ): TemperatureState => { switch (action.type) { case "SET_CELSIUS": return { ...state, celsius: action.payload, fahrenheit: action.formattedFahrenheit, }; case "SET_FAHRENHEIT": return { ...state, fahrenheit: action.payload, celsius: action.formattedCelsius, }; default: return state; } }; const App: React.FC = () => { const [state, dispatch] = useReducer(temperatureReducer, initialState); const { celsius, fahrenheit } = state; const formatValue = (value: number) => { return value.toFixed(); }; const handleCelsiusChange = (e: React.ChangeEvent<HTMLInputElement>) => { const celsiusValue = e.target.value; const formattedFahrenheit = celsiusValue ? formatValue((parseFloat(celsiusValue) * 9) / 5 + 32) : ""; dispatch({ type: "SET_CELSIUS", payload: celsiusValue, }); }; const handleFahrenheitChange = (e: React.ChangeEvent<HTMLInputElement>) => { const fahrenheitValue = e.target.value; const formattedCelsius = fahrenheitValue ? formatValue(((parseFloat(fahrenheitValue) - 32) * 5) / 9) : ""; dispatch({ type: "SET_FAHRENHIET", payload: fahrenheitValue, formattedCelsius, }); }; return ( <div className="p-8"> <h1 className="mb-4 text-2xl">Temperature</h1> <div className="flex gap-4 mb-4"> <div className="border border-zinc-400 rounded-md overflow-hidden shadow-md"> <input className="input input-bordered w-full text-center text-2xl p-1 focus:outline-none bg-zinc-50 text-zinc-600" data-testid="celsius-input" onChange={handleCelsiusChange} placeholder="0" type="number" value={celsius} /> <div className="bg-zinc-300 px-4 py-1 text-zinc-900">Celsius</div> </div> <span className="text-3xl text-zinc-900">=</span> <div className="border border-zinc-400 rounded-md overflow-hidden shadow-md"> <input className="input input-bordered w-full text-center text-2xl p-1 focus:outline-none bg-zinc-50 text-zinc-600" data-testid="fahrenheit-input" onChange={handleFahrenheitChange} placeholder="0" type="number" value={fahrenheit} /> <div className="bg-zinc-300 px-4 py-1 text-zinc-900">Fahrenheit</div> </div> </div> <div className="flex gap-4 text-sm w-fit items-center"> <div className="bg-yellow-300 text-yellow-950 px-2 py-1 rounded-sm"> Formula </div> <div className="text-gray-600">(0°C × 9/5) + 32 = 32°F</div> </div> </div> ); }; export default App;
Users experience an issue where inputting a value into the Celsius field does not update the Fahrenheit field as expected. Similarly, when inputting a value into the Fahrenheit field, the Celsius field does not update accordingly.
When a user enters a value in the Celsius input, the Fahrenheit field should automatically update to show the converted temperature. Conversely, entering a value in the Fahrenheit input should update the Celsius field accordingly. The action types and properties must be correct to ensure proper state updates.
Tests