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>