Answer the question
In order to leave comments, you need to log in
Why does component auto-render using DateTimePicker from material-ui/pickers?
Good afternoon, colleagues!
In the project, I use the material-ui/pickers library. I need to implement a search in a table by the user's registration date. I applied the DateTimePicker component. There is a date FROM the DateTimePicker (one component), a date AFTER (the second component)
There was a problem: one date is selected, then the second, and autorun immediately works. When one of the dates is selected, the modal window does not close, it waits for the user's action. At the first, then the second date (the order does not matter), autorun is triggered.
The question is, is there some kind of slide effect in the DateTimePicker component that I don't know about?
I'll be glad for any hint.
PS Below is the code of my component, maybe it will help to clarify the situation
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>
);
};
Answer the question
In order to leave comments, you need to log in
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question