I have an issue where two functions call each other in a .tsx file and this is causing an ESLint error when I try run storybook. The error that results is:
'handleChange' was used before it was defined
Swopping the order in which they are defined simply causes the same error for the other function "createDropdown".
Ive tried moving all but the return call to reside outside of the main const WrapupCodes
function but this results the the same issues.
What is the normal manner to handle this situation ?
import { Button, MenuItem, Select, SelectChangeEvent } from "@mui/material";
import "./style.css";
export type WrapupCodesProps = {
wrapupCodes: object;
};
const WrapupCodes = () => {
const wrapupCodes = {
"Customer Service": {
"Customer Complaint": {
Ongoing: "*",
Resolved: "*",
},
"Customer Review": {
Dissatisfied: "*",
Satisfied: "*",
},
},
Returns: {
"Exchange goods": "*",
"Partial refund": "*",
"Returned for full refund": "*",
},
};
const wrapupCodesList: JSX.Element[] = [];
const currentWrapupKey = wrapupCodes;
let wrapupComplete = false;
const createDropdown = (objKey: string) => {
const menuItems: JSX.Element[] = [];
// @ts-ignore
Object.entries(currentWrapupKey[objKey]).forEach(([key]) => {
menuItems.push(<MenuItem value={key}>{key}</MenuItem>);
});
wrapupCodesList.push(
<Select
label="Wrapup Code"
className="wrapup-codes--dropdown"
onChange={handleChange}
>
{menuItems}
</Select>
);
};
const handleChange = (event: SelectChangeEvent) => {
createDropdown(event.target.value as string);
};
wrapupComplete = true;
const closeContactButton = wrapupComplete ? (
<Button
className="wrapup-codes--button"
variant="contained"
color="success"
onClick={() => {
alert("Contact Closed");
}}
>
Close Contact
</Button>
) : (
<></>
);
return (
<form data-testid="wrapupCodes" className="wrapup-codes">
{wrapupCodesList}
{closeContactButton}
</form>
);
};
export default WrapupCodes;
CodePudding user response:
Because that is a linter rule. It won't affect TypeScript compilation. Just add this line before the handleChange
function as follow:
(Example for ESLint)
//eslint-disable-next-line no-use-before-define
onChange={handleChange}
Related:
This will change the structure so personal not preferred.
Put the function inside another one
CodePudding user response:
You should store the selected value in state.
When the state changes, React will 'react' to that state change and rerender.
If you understand the above and functional programming concepts it will help a lot and you will write your components in the correct manner.
createDropdown
is a function declaration.
wrapupComplete = false;
and then declaring a function and then setting wrapupComplete = true;
will not do anything.
Here is a playground, adjusted with the correct technique.