ReactJS state dependends on another state [closed]

I have a component that contains a range date picker and interval components. The interval depends on the date range. The generateDefaultDateIntervalLimitations() function assigns available interval options, and the rest are disabled according to the date range.

My problem is that when the date changes, useEffect sets dateTimeInterval. Because the date has changed, it also changes the interval state. When the interval state changes, it sets dateTimeInterval again. This is normal, but my request depends on setDateTimeInterval, which is defined in the parent component. As soon as this changes, it re-renders the parent component, which has child components with React Query and Axios requests. This causes the request to be sent twice because the state changes first for the date and then for the interval. The interval itself can be changed as well, but only once.

There are 3 cases:

  1. When date changed, interval changed as well
  2. When date changed interval can be the same value for example date range if applied 3 months then interval is 30 seconds, if users changes it to 2 month then still interval is 30 seconds
  3. When user just only changes interval.
const generateDefaultDateIntervalLimitations = (t) => [
  {
    dateDifference: 2592000,
    dateUnit: "second",
    intervals: [
      { label: `30 ${t("sec")}`, value: 30, disabled: false },
      { label: `1 ${t("min")}`, value: 60, disabled: false },
      { label: `5 ${t("min")}`, value: 300, disabled: false },
      { label: `10 ${t("min")}`, value: 600, disabled: false },
      { label: `15 ${t("min")}`, value: 900, disabled: false },
      { label: `30 ${t("min")}`, value: 1800, disabled: false },
      { label: `1 ${t("hour")}`, value: 3600, disabled: false },
      { label: `12 ${t("hours")}`, value: 43200, disabled: false },
      { label: `24 ${t("hours")}`, value: 86400, disabled: false },
    ],
  },
  {
    dateDifference: 7776000,
    dateUnit: "second",
    intervals: [
      { label: `30 ${t("sec")}`, value: 30, disabled: true },
      { label: `1 ${t("min")}`, value: 60, disabled: true },
      { label: `5 ${t("min")}`, value: 300, disabled: true },
      { label: `10 ${t("min")}`, value: 600, disabled: true },
      { label: `15 ${t("min")}`, value: 900, disabled: false },
      { label: `30 ${t("min")}`, value: 1800, disabled: false },
      { label: `1 ${t("hour")}`, value: 3600, disabled: false },
      { label: `12 ${t("hours")}`, value: 43200, disabled: false },
      { label: `24 ${t("hours")}`, value: 86400, disabled: false },
    ],
  },
  {
    dateDifference: 13132800,
    dateUnit: "second",
    intervals: [
      { label: `30 ${t("sec")}`, value: 30, disabled: true },
      { label: `1 ${t("min")}`, value: 60, disabled: true },
      { label: `5 ${t("min")}`, value: 300, disabled: true },
      { label: `10 ${t("min")}`, value: 600, disabled: true },
      { label: `15 ${t("min")}`, value: 900, disabled: true },
      { label: `30 ${t("min")}`, value: 1800, disabled: true },
      { label: `1 ${t("hour")}`, value: 3600, disabled: false },
      { label: `12 ${t("hours")}`, value: 43200, disabled: false },
      { label: `24 ${t("hours")}`, value: 86400, disabled: false },
    ],
  },
  {
    dateDifference: 15724800,
    dateUnit: "second",
    intervals: [
      { label: `30 ${t("sec")}`, value: 30, disabled: true },
      { label: `1 ${t("min")}`, value: 60, disabled: true },
      { label: `5 ${t("min")}`, value: 300, disabled: true },
      { label: `10 ${t("min")}`, value: 600, disabled: true },
      { label: `15 ${t("min")}`, value: 900, disabled: true },
      { label: `30 ${t("min")}`, value: 1800, disabled: true },
      { label: `1 ${t("hour")}`, value: 3600, disabled: false },
      { label: `12 ${t("hours")}`, value: 43200, disabled: false },
      { label: `24 ${t("hours")}`, value: 86400, disabled: false },
    ],
  },
  {
    dateDifference: 31622400,
    dateUnit: "second",
    intervals: [
      { label: `30 ${t("sec")}`, value: 30, disabled: true },
      { label: `1 ${t("min")}`, value: 60, disabled: true },
      { label: `5 ${t("min")}`, value: 300, disabled: true },
      { label: `10 ${t("min")}`, value: 600, disabled: true },
      { label: `15 ${t("min")}`, value: 900, disabled: true },
      { label: `30 ${t("min")}`, value: 1800, disabled: true },
      { label: `1 ${t("hour")}`, value: 3600, disabled: true },
      { label: `12 ${t("hours")}`, value: 43200, disabled: false },
      { label: `24 ${t("hours")}`, value: 86400, disabled: false },
    ],
  },
  {
    dateDifference: 94694400,
    dateUnit: "second",
    intervals: [
      { label: `30 ${t("sec")}`, value: 30, disabled: true },
      { label: `1 ${t("min")}`, value: 60, disabled: true },
      { label: `5 ${t("min")}`, value: 300, disabled: true },
      { label: `10 ${t("min")}`, value: 600, disabled: true },
      { label: `15 ${t("min")}`, value: 900, disabled: true },
      { label: `30 ${t("min")}`, value: 1800, disabled: true },
      { label: `1 ${t("hour")}`, value: 3600, disabled: true },
      { label: `12 ${t("hours")}`, value: 43200, disabled: true },
      { label: `24 ${t("hours")}`, value: 86400, disabled: false },
    ],
  },
];
const DatePickerInterval = ({
  setDateTimeInterval,
  intervalStorageKey,
  intervalStorageOptions,
  isRangePicker,
  showTime,
  defaultDate,
  dateStorageKey,
  dateStorageOptions,
  dateIntervalLimitations,
}) => {
  const [options, setOptions] = useState(null);
  const { t } = useTranslation();
  const [date, setDate] = useState(null);
  const [interval, setInterval] = useState(null);

  const limitations = useMemo(
    () => dateIntervalLimitations || generateDefaultDateIntervalLimitations(t),
    [dateIntervalLimitations, t],
  );

  useEffect(() => {
    if (date) {
      const applyLimitations = (limitations) => {
        const difference = calculateDateDifference("second");
        return (
          limitations.find((lim) => difference <= lim.dateDifference)
            ?.intervals || []
        );
      };

      const calculateDateDifference = (unit) => {
        return date[1]?.diff(date[0], unit) || 0;
      };

      const limitedIntervals = applyLimitations(limitations);
      setOptions(limitedIntervals);
    }
  }, [date, limitations]);

  useEffect(() => {
    if (options?.length > 0) {
      setInterval(options.find((option) => !option.disabled)?.value || 0);
    }
  }, [options]);

  useEffect(() => {
    if (date && interval) {
      setDateTimeInterval({
        date: {
          dateBegin: date[0],
          dateEnd: date[1],
        },
        interval: interval,
      });
    }
  }, [date || (date && interval)]);

  return (
    <>
      <Interval
        setInterval={setInterval}
        interval={interval}
        storageKey={intervalStorageKey}
        storageOptions={intervalStorageOptions}
        options={options}
      />
      <CustomDatePicker
        isRangePicker={isRangePicker}
        showTime={showTime}
        date={date}
        defaultDate={defaultDate}
        setDate={setDate}
        storageKey={dateStorageKey}
        storageOptions={dateStorageOptions}
      />
    </>
  );
};

export default DatePickerInterval;

What i have tried is to use condition logic in useEffect but it does help in case when user updates availble interval it does not send request because it does not catch interval change, for rest cases it works