Home > other >  Unable to render classnames based on switch statement in ReactJS
Unable to render classnames based on switch statement in ReactJS

Time:01-04

I am trying to render badges in different colours based on the payment status of an order, but I keep getting a;

buttonColour is not defined
{(() => {
    let buttonColour

    switch (paymentstatus) {
        case "Paid": return buttonColour = "bg-green-100 text-green-800"
        case "Pending": return buttonColour = "bg-yellow-100 text-yellow-800"
        case "Failed": return buttonColour = "bg-red-100 text-red-800"
    }
})()}
<td className="whitespace-nowrap px-3 py-4 text-sm text-gray-500">
    <span className={`${buttonColour} inline-flex items-center rounded-md px-2.5 py-0.5 text-sm font-medium`}>{paymentstatus}</span>
</td>

CodePudding user response:

The anonymous function exists in a block that has no effect on the rest of the code.

You'd like to set the variable outside the IIFE and use the switch statement to update the value of buttonColour.

However, try to use states to make the buttonColor variable reactive. Also, whenever you, can try to keep the logic outside the JSX.

CodePudding user response:

{(() => {
let buttonColour

switch (paymentstatus) {
    case "Paid": return buttonColour = "bg-green-100 text-green-800"
    case "Pending": return buttonColour = "bg-yellow-100 text-yellow-800"
    case "Failed": return buttonColour = "bg-red-100 text-red-800"
}
})()}

here buttonColour variable block scope end you cannot use this variable outside

<td className="whitespace-nowrap px-3 py-4 text-sm text-gray-500">
<span className={`${buttonColour} inline-flex items-center rounded-md px-2.5 py-0.5 text-sm font-medium`}>{paymentstatus}</span>

hence you cannot use buttonColour

It will best for you to keep the logic in seperate hook that will render new buttonColor value when paymentStatus change

usePaymentStatus.jsx

import { useEffect, useState } from "react";

export default function usePaymentStatus(paymentStatus) {
  const [buttonColor, setButtonColor] = useState("");
  useEffect(() => {
    switch (paymentStatus) {
      case "Paid":
        setButtonColor("bg-green-100 text-green-800");
        break;
      case "Pending":
        setButtonColor("bg-yellow-100 text-yellow-800");
        break;

      case "Failed":
        setButtonColor("bg-red-100 text-red-800");
        break;
      default:
        setButtonColor("");
    }
  }, [paymentStatus]);
  return {
    buttonColor
  };
}

Then inside your App

import "./styles.css";
import usePaymentStatus from "./usePaymentStatus";

export default function App() {
  const paymentstatus = "Pending";
  const { buttonColor } = usePaymentStatus(paymentstatus);


  return (
    <div className="App">
      <td className="whitespace-nowrap px-3 py-4 text-sm text-gray-500">
        <span
          className={`${buttonColor} inline-flex items-center rounded-md px-2.5 py-0.5 text-sm font-medium`}
        >
          {paymentstatus}
        </span>
      </td>
    </div>
  );
}

CodePudding user response:

Its a scope issue. buttonColor is not accessible in your span.

I would suggest a different approach

const classes = {
  "Paid": "bg-green-100 text-green-800",
  "Pending": "bg-yellow-100 text-yellow-800",
  "Failed": "bg-red-100 text-red-800",
}

and in your span use like this -

<span className={`${classes[paymentstatus] || ''} inline-flex items-center rounded-md px-2.5 py-0.5 text-sm font-medium`}>{paymentstatus}</span>

If you want to use a switch then create a function and call that.

Example:

const getClasses = useCallback( (paymentstatus) =>{

    let buttonColour  = '';
    switch (paymentstatus) {
        case "Paid": 
            buttonColour = "bg-green-100 text-green-800"; 
            break
        case "Pending": 
            buttonColour = "bg-yellow-100 text-yellow-800";
            break;
        case "Failed": 
            buttonColour = "bg-red-100 text-red-800";
            break;
         default:
    }
}, []);

In your span use like this

<span className={`${getClasses(paymentstatus)} inline-flex items-center rounded-md px-2.5 py-0.5 text-sm font-medium`}>{paymentstatus}</span>
  • Related