@EvgenJunior

Почему происходит автоматический рендеринг компонента с использованием DateTimePicker из material-ui/pickers?

Добрый день, коллеги!
В проекте я использую библиотеку material-ui/pickers. Мне нужно реализовать поиск в таблице по дате регистрации пользователя. Я применил компонент DateTimePicker. Есть дата ОТ DateTimePicker(один компонент), дата ПОСЛЕ(второй компонент)
Возникла проблема: выбирается одна дата, затем вторая и сразу срабатывает автозапуск. При выборе одной из дат, модальное окно не закрывается, ждет действия пользователя. При первой, затем второй даты(порядок не имеет значения) срабатывает автозапуск.
Вопрос в следующем может какой-то слайд эффект есть в компоненте DateTimePicker о котором я не знаю?
Буду рад за любую подсказку.
P.S. Ниже приведен код моего компонента, может поможет разъяснить ситуацию

import React, { useEffect, useState } from 'react';
import ClearIcon from '@material-ui/icons/Clear';
import ukLocale from 'date-fns/locale/uk';
import { DateTimePicker, MuiPickersUtilsProvider } from '@material-ui/pickers';
import DateFnsUtils from '@date-io/date-fns';
import {
  Box,
  createStyles,
  IconButton,
  makeStyles,
  Theme,
  Typography
} from '@material-ui/core';
import { useHistory } from 'react-router-dom';
import {
  useBuildUrlWithoutGetParameter,
  useGetParameter,
  useSetGetParameter
} from '../../../general/hooks/get-parameter.hook';
import { usePreviousValue } from '../../../general/hooks/previous-value.hook';
import { TDateSearch } from '../type';

interface IDateSearch {
  dataKey: string;
  inDateValue: TDateSearch;
}

const useStyles = makeStyles((theme: Theme) => {
  return createStyles({
    dataTimePicker: {
      width: '300px',
      paddingRight: '14px'
    },
    box: {
      display: 'flex'
    }
  });
});

export const SearchDate: React.FC<IDateSearch> = ({ dataKey, inDateValue }) => {
  const classes = useStyles();
  const beforeDateKey = `${dataKey}[before]`;
  const afterDateKey = `${dataKey}[after]`;
  const getParameterBefore = useGetParameter(`${beforeDateKey}`);
  const getParameterAfter = useGetParameter(`${afterDateKey}`);

  // инициализация стартового значения для state
  const initFromDateValue =
    getParameterBefore === null
      ? inDateValue.fromCreateDate
      : new Date(getParameterBefore);

  const initToDateValue =
    getParameterAfter === null
      ? inDateValue.fromCreateDate
      : new Date(getParameterAfter);

  // state для получения данных из DataTimePicker
  const [
    selectedBeforeCreateDate,
    setSelectedBeforeCreateDate
  ] = useState<Date | null>(initFromDateValue);
  const [
    selectedAfterCreateDate,
    setSelectedAfterCreateDate
  ] = useState<Date | null>(initToDateValue);

  const prevValueBeforeCreateDate = usePreviousValue(selectedBeforeCreateDate);
  const prevValueAfterCreateDate = usePreviousValue(selectedAfterCreateDate);

  const history = useHistory();

  const dateValue = (arg: Date | null) => {
    if (arg !== null) {
      return arg.toISOString();
    }
    return '';
  };

  const getParametersBefore = {
    [beforeDateKey]: dateValue(selectedBeforeCreateDate)
  };
  const getParametersAfter = {
    [afterDateKey]: dateValue(selectedAfterCreateDate)
  };

  const urlBefore = useSetGetParameter(getParametersBefore);
  const urlAfter = useSetGetParameter(getParametersAfter);
  const urlBeforeWithoutGetParameter = useBuildUrlWithoutGetParameter([
    beforeDateKey
  ]);
  const urlAfterWithoutGetParameter = useBuildUrlWithoutGetParameter([
    afterDateKey
  ]);

  const DateBeforeChange = (date: Date | null) => {
    setSelectedBeforeCreateDate(date);
  };
  const DateAfterChange = (date: Date | null) => {
    setSelectedAfterCreateDate(date);
  };

  useEffect(() => {
    if (
      prevValueBeforeCreateDate?.toISOString() ===
      selectedBeforeCreateDate?.toISOString()
    ) {
      if (selectedBeforeCreateDate === null) {
        history.push(urlBeforeWithoutGetParameter);
      } else {
        history.push(urlBefore);
      }
    }
  }, [
    history,
    prevValueBeforeCreateDate,
    selectedBeforeCreateDate,
    urlBefore,
    urlBeforeWithoutGetParameter
  ]);

  useEffect(() => {
    if (
      prevValueAfterCreateDate?.toISOString() ===
      selectedAfterCreateDate?.toISOString()
    ) {
      if (selectedAfterCreateDate !== null) {
        history.push(urlAfter);
      } else {
        history.push(urlAfterWithoutGetParameter);
      }
    }
  }, [
    history,
    prevValueAfterCreateDate,
    selectedAfterCreateDate,
    urlAfter,
    urlAfterWithoutGetParameter
  ]);

  const resetBeforeDate = (event: React.MouseEvent<HTMLButtonElement>) => {
    event.stopPropagation();
    setSelectedBeforeCreateDate(null);
  };
  const resetAfterDate = (event: React.MouseEvent<HTMLButtonElement>) => {
    event.stopPropagation();
    setSelectedAfterCreateDate(null);
  };

  return (
    <Box>
      <Typography align='center' component='h5'>
        Поиск по дате создания
      </Typography>
      <MuiPickersUtilsProvider utils={DateFnsUtils} locale={ukLocale}>
        <DateTimePicker
          margin='normal'
          inputVariant='outlined'
          className={classes.dataTimePicker}
          autoOk={false}
          ampm={false}
          disableFuture
          value={selectedBeforeCreateDate}
          onChange={DateBeforeChange}
          label='З'
          okLabel='Подтвердить'
          cancelLabel='Отменить'
          clearLabel='Очистить'
          InputLabelProps={{ style: { fontSize: '20px' } }}
          format='yyyy-MM-dd HH:mm:ss'
          clearable
          variant='dialog'
          invalidDateMessage='Недопустимый формат'
          maxDateMessage='Дата не должна быть позже максимальной даты'
          maxDate={selectedAfterCreateDate}
          InputProps={{
            endAdornment: (
              <IconButton onClick={resetBeforeDate}>
                <ClearIcon />
              </IconButton>
            )
          }}
        />
        <DateTimePicker
          margin='normal'
          inputVariant='outlined'
          className={classes.dataTimePicker}
          autoOk={false}
          ampm={false}
          minDate={selectedBeforeCreateDate}
          disableFuture
          value={selectedAfterCreateDate}
          onChange={DateAfterChange}
          label='До'
          okLabel='Подтвердить'
          cancelLabel='отменить'
          clearLabel='Очистить'
          InputLabelProps={{ style: { fontSize: '20px' } }}
          format='yyyy-MM-dd HH:mm:ss'
          maxDateMessage='Дата не должна быть позже максимальной даты'
          clearable
          variant='dialog'
          InputProps={{
            endAdornment: (
              <IconButton onClick={resetAfterDate}>
                <ClearIcon />
              </IconButton>
            )
          }}
        />
      </MuiPickersUtilsProvider>
    </Box>
  );
};
  • Вопрос задан
  • 57 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы