Live Preview
Coding Workspace
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;
Level:
intermediate

Temperature fields do not update correspondingly

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.

Steps to Reproduce

  1. Enter a numeric value in the Celsius input field.
  2. Observe that the Fahrenheit field does not update corresponding to the input value.
  3. Enter a numeric value in the Fahrenheit input field.
  4. Observe that the Celsius field does not update correctly, and the application might exhibit further errors due to the typo in the action type.

Expected Behavior

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.

Need help?

Open browser consoleTests