Tim Launders
Tim Launders

Reputation: 249

how to reset dialog in react after close

The code below I have provided , one example opens the dialog. And the dialog has add functionality which is the addEmail where in you can add multiple fields which is inside the dialog.

I wanna know is that when I close the dialog using the onClick={handleClose} it should reset the dialog, fields that I added should not show after I close since I did not save it.

So when I click cancel it should reset the state.

Thanks for any idea.

for example here I added fields when I close this and open again these field should not show cause it should reset when I close.

enter image description here

#interface.ts

export type EditPropertiesProps = {
  open: boolean;
  handleClose: () => void;
  selectedRow: IRegional
};

#Code snippet - main page --- this calls and opens the dialog

 const handleClose = () => {
    console.log('here')
    setOpen(false);
  };

    <EditProperties open={open} handleClose={handleClose} selectedRow={selectedRow} />

#EditProperties ts code

export const RegionalListData: IRegionalList[] = [
  {
    id: 4,
    name: "Associate Director of Construction Ops",
    column: "associateDirectorofConstructionOps",
    emails: [
      {
        emailAddress: "[email protected]",
        firstName: "Associate",
        lastName: "Director",
        id: Math.floor(Math.random() * 999),
        fetching: false,
      },
    ],
  },
  {
    id: 5,
    name: "CAM Manager",
    column: "camManager",
    emails: [
      {
        emailAddress: "[email protected]",
        firstName: "Associate",
        lastName: "Director",
        id: Math.floor(Math.random() * 999),
        fetching: false,
      },
    ],
  },
  {
    id: 6,
    name: "CAO-Chief Administrative Officer",
    column: "caoChiefAdministrativeOfficer",
    emails: [
      {
        emailAddress: "[email protected]",
        firstName: "Associate",
        lastName: "Director",
        id: Math.floor(Math.random() * 999),
        fetching: false,
      },
    ],
  },
];
type InitialReqPaylod = {
  accountId: number;
  regionalRoleUserDto: IRegional;
};
type IData = {
  regionName: string;
  marketName: string;
  subRegionName: string;
};
type IEmail = {
  emailAddress: string;
  firstName: string;
  id: number;
  lastName: string;
};
const EditProperties: FC<EditPropertiesProps> = ({
  open,
  handleClose,
  selectedRow,
}) => {
  const dispatch = useAppDispatch();
  const [isEmailOpen, setOpenEmail] = useState(false);
  const [fetching, setFetching] = useState(false);
  const [RegionalList, setRegionalList] = useState<IRegionalList[]>(
    RegionalListData
  );
  const [data, setData] = useState<IData>({
    regionName: "",
    marketName: "",
    subRegionName: "",
  });
  const [regionalId, setRegionalId] = useState<number | null>(null);
  const [emailCurrentIndex, setEmailCurrentIndex] = useState<number | null>(
    null
  );
  const [selectedEmailId, setSelectedEmailId] = useState<number | null>(null);
  const { isSuccess } = useAppSelector((state) => state.yardUser);
  const { isSaveSuccess } = useAppSelector((state) => state.region);
  const email = useAppSelector((state) => state.yardUser);
  const [emailOptions, setEmailOptions] = useState<IEmail[]>([]);

  const emailList = email.data ? email.data.data : [];



  useEffect(() => {
    if (selectedRow) {
      setData({
        regionName: selectedRow["regionName"],
        marketName: selectedRow["marketName"],
        subRegionName: selectedRow["subRegionName"],
      });

      let regional = [...RegionalList];
      for (const k in selectedRow) {
        regional.map((prop: IRegionalList) => {
          if (prop.column === k) {
            prop.emails = selectedRow[k] ? selectedRow[k] : [];
          }
        });
      }
      setRegionalList(regional);
    }
  }, [selectedRow]);
  const [maxWidth, setMaxWidth] = React.useState<DialogProps["maxWidth"]>("md");
  const fetchEmailResult = React.useMemo(
    () =>
      throttle(
      (event: any, callback: (results: IEmail[]) => void) => {
        const payload: IYardUserRequestPayload | InitialReqPaylod = {
          accountId: 1,
          searchString: event.target.value,
        };
        fetch(
            `https://jsonplaceholder.typicode.com/users?email=${event.target.value}`
          )
            .then((res) => res.json())
            .then((res) => res.data ? callback(res.data.slice(0, 10)) : callback([]))
      },
      200
    ),
    []
    );

  const emailOnChange = (event: any, regionalId: number, index: number, emailId: number) => {
    setRegionalId(regionalId);
    setEmailCurrentIndex(index);
    setSelectedEmailId(emailId);
    fetchEmailResult(event,(results: IEmail[]) => {
      console.log('results' , results)
      if (results.length) setEmailOptions(results);
    });
  };

  useEffect(() => {
    if (isSaveSuccess) {
      handleClose();
    }
  }, [isSaveSuccess]);
  useEffect(() => {
    if (isSuccess) {
      setFetching(false);
    }
  }, [isSuccess]);

  const addEmail = (id: number) => {
    setRegionalList((list) =>
      list.map((item) => {
        if (item.id === id) {
          return {
            ...item,
            emails: [
              ...item.emails,
              {
                emailAddress: "",
                firstName: "",
                lastName: "",
                id: Math.floor(Math.random() * 999),
                fetching: false,
              },
            ],
          };
        }
        return item;
      })
    );
  };

  const deleteEmail = (email: IEmail, regionId: number) => {
    const regionalListCopy = [...RegionalList].map((prop: IRegionalList) => {
      if (prop.id === regionId) {
        return {
          ...prop,
          emails: prop.emails.filter((prop) => prop.id !== email.id),
        };
      }
      return { ...prop };
    });
    setRegionalList(regionalListCopy);
  };

  const setOnChangeOption = (email) => {
    setSelectedEmailId(null);
    setRegionalList((list) =>
      list.map((item) => {
        if (item.id === regionalId) {
          return {
            ...item,
            emails: [
              ...item.emails.map((prop) => {
                return {
                  ...prop,
                  ...email,
                };
              }),
            ],
          };
        }
        return item;
      })
    );
  };

  const EmailItem = ({ email, mIndex, prop }) => (
    <>
      <div style={{ display: "block" }} key={email.id}>
          <div
            style={{
              display: "flex",
              justifyContent: "space-between",
              alignItems: "center",
              marginTop: 15
            }}
          >
            <Autocomplete
              options={emailOptions}
              getOptionLabel={(option: IEmail) => option.emailAddress}
              onInputChange={($event) => emailOnChange($event, prop.id, mIndex, email.id)}
              onChange={($event, value) => setOnChangeOption(value)}
              fullWidth
              open={email.id === selectedEmailId}
              renderInput={(params) => (
                <TextField size="small" {...params} variant="standard" />
              )}
              renderOption={(props, option) => {
                return (
                  <Box component="li" {...props}>
                    {option.emailAddress}
                  </Box>
                );
              }}
            />
            <DeleteIcon
              style={{ color: "red", cursor: "pointer" }}
              onClick={() => deleteEmail(email, prop.id)}
            />
          </div>
        <div
          style={{
            fontSize: ".8em",
            display: "flex",
            justifyContent: "space-between",
          }}
        >
          <span style={{ paddingTop: 5 }}>
            Email : {email.emailAddress}
            Full Name: {email.firstName} {email.lastName}
          </span>
          {/* <span style={{ paddingRight : 40 }}>{fetching ? "Fetching...." : null}</span> */}
        </div>
      </div>
    </>
  );


  return (
    <Dialog
      maxWidth={maxWidth}
      open={open}
      onClose={handleClose}
      aria-labelledby="alert-dialog-title"
      aria-describedby="alert-dialog-description"
    >
      <DialogTitle id="alert-dialog-title">Edit</DialogTitle>

      <DialogContent>
        <Card sx={{ minWidth: 275 }} style={{ padding: 20 }}>
          <div>
            <span>Sub-Region (Sub-Division)</span>
            <Divider style={{ marginTop: 10 }} />
            <FormControl sx={{ mt: 2, minWidth: 720 }}>
              <TextField
                label="Region (Division)"
                variant="filled"
                value={data.regionName}
              />
            </FormControl>
          </div>
          <div style={{ marginTop: 10 }}>
            <span>Sub-Region (Sub-Division)</span>
            <Divider style={{ marginTop: 10 }} />
            <FormControl sx={{ mt: 2, minWidth: 720 }}>
              <TextField
                label="Sub-Region (Sub-Division)"
                variant="filled"
                value={data.subRegionName}
              />
            </FormControl>
          </div>
          <div style={{ marginTop: 10 }}>
            <span>Market</span>
            <Divider style={{ marginTop: 10 }} />
            <FormControl sx={{ mt: 2, minWidth: 720 }}>
              <TextField
                label="Market"
                variant="filled"
                value={data.marketName}
              />
            </FormControl>
          </div>
        </Card>
        {RegionalList.map((prop: IRegionalList, index: number) => (
          <Card
            sx={{ minWidth: 275 }}
            style={{ overflow: "visible", padding: 20, marginTop: 20 }}
            key={prop.id}
          >
            <div style={{ display: "flex", alignItems: "center" }}>
              {prop.name}*{" "}
              <AddIcon
                style={{ marginLeft: 5, cursor: "pointer" }}
                onClick={() => addEmail(prop.id)}
              />
            </div>
            <Divider style={{ marginTop: 10 }} />
            {prop.emails.map((email: IEmail, mIndex: number) => (
              <EmailItem
                key={email.id}
                prop={prop}
                email={email}
                mIndex={mIndex}
              />
            ))}
          </Card>
        ))}
      </DialogContent>
      <DialogActions
        style={{ marginTop: "20px", marginRight: "20px", marginBottom: "20px" }}
      >
        <Button onClick={handleClose}>Cancel</Button>
        <Button variant="contained" onClick={() => saveChanges()} autoFocus>
          Save Changes
        </Button>
      </DialogActions>
    </Dialog>
  );
};

export default EditProperties;

Upvotes: 0

Views: 3493

Answers (2)

Taig
Taig

Reputation: 7288

Generally speaking, if a component has internal state (e.g. useState) the straightforward way to reset that state (especially when working with dialogs), is to unmount and then remount the component.

So instead of doing ...

const handleClose = () => {
  setOpen(false);
};

<EditProperties open={open} handleClose={handleClose} selectedRow={selectedRow} />

... you could be doing this:

const handleClose = () => {
  setOpen(false);
};

{open && <EditProperties open handleClose={handleClose} selectedRow={selectedRow} />}

But again, this only matters for local state of the dialog. If your unexpected behaviour is coming from the selectedRow prop, you will have to manage that state manually.

Upvotes: 3

Elvin
Elvin

Reputation: 584

You need just reset all used states as values of form when clicking handleClose, my suggestion would be to use just one object state for form values.

Example:

const onClose = () => {
    handleClose();
    setRegionalList(RegionalListData);
   } 

return (
    <Dialog
      maxWidth={maxWidth}
      open={open}
      onClose={onClose}
      aria-labelledby="alert-dialog-title"
      aria-describedby="alert-dialog-description"
    >

Upvotes: 1

Related Questions