Home > Back-end >  Typescript functions calling each other in same script
Typescript functions calling each other in same script

Time:05-05

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}

ESLint: no-use-before-define

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.

  • Related