react-datepicker
react-datepicker copied to clipboard
customInput remounts on every render
Hi, I think there's a performance issue when using customInput option with react-datepicker. The provided custom input gets created/mounted on every render of the parent.
The problem can be seen in this sandbox:
Here I was testing it together with react-hook-form, but I commented the integration to prove the problem is on the datepicker. I followed the example here -> https://reactdatepicker.com/#example-custom-input.
I added local state (open) to force parent rendering, and useEffect to log the element remounting.
This may not seem like a big problem, but this is a simple example. On my project I'm using a heavier custom element and the performance hit is pretty obvious.
I don't know if the solution is fixable here or I'm gonna have to use some kind of hook/memoization. Any clues?
Thanks and keep up the good work !
- OS: Ubuntu on WLS
- Browser Chrome
- Version 86
Oh, and seems forwardRef is also necessary, as commented by @Psvensso on this other issue https://github.com/Hacker0x01/react-datepicker/issues/2397#issuecomment-707048538
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Same here. This is even more visible when you pass onChange
handler, and try to manually type the date. You will lose focus on each render.
In my case, adding useMemo
hook solve the issue
const CustomInput = React.useMemo(
() => forwardRef((props, ref) => <input {...props} ref={ref} />),
[],
);
Same here. This is even more visible when you pass
onChange
handler, and try to manually type the date. You will lose focus on each render.In my case, adding
useMemo
hook solve the issueconst CustomInput = React.useMemo( () => forwardRef((props, ref) => <input {...props} ref={ref} />), [], );
Could you post a full example of this? Thanks!
If anyone is looking for full example here it is with custom tailwind component
const DatePicker = ({
value,
onChange,
label,
showError,
placeholder,
}: IDatePicker): JSX.Element => {
const ref = createRef<HTMLInputElement>();
const CustomInput = useMemo(
() =>
forwardRef<HTMLInputElement, unknown>(({ ...rest }) => (
<div className={styles['outline-container']}>
{label && <label>{label}</label>}
<input
ref={ref}
{...rest}
className={!value && showError ? 'input-error' : ''}
type="text"
autoComplete="bday"
/>
<Icon
className={`absolute text-gray-500 right-4 ${
label ? '' : '-translate-y-1/2'
} top-1/2 transform stroke-current`}
name="calendar"
/>
</div>
)),
[]
);
return (
<ReactDatePicker
customInput={<CustomInput ref={ref} />}
selected={value}
locale={ru}
dateFormat="dd.MM.yyyy"
portalId="root"
onChange={onChange}
placeholderText={placeholder}
/>
);
};
If anyone is looking for full example here it is with custom tailwind component
const DatePicker = ({ value, onChange, label, showError, placeholder, }: IDatePicker): JSX.Element => { const ref = createRef<HTMLInputElement>(); const CustomInput = useMemo( () => forwardRef<HTMLInputElement, unknown>(({ ...rest }) => ( <div className={styles['outline-container']}> {label && <label>{label}</label>} <input ref={ref} {...rest} className={!value && showError ? 'input-error' : ''} type="text" autoComplete="bday" /> <Icon className={`absolute text-gray-500 right-4 ${ label ? '' : '-translate-y-1/2' } top-1/2 transform stroke-current`} name="calendar" /> </div> )), [] ); return ( <ReactDatePicker customInput={<CustomInput ref={ref} />} selected={value} locale={ru} dateFormat="dd.MM.yyyy" portalId="root" onChange={onChange} placeholderText={placeholder} /> ); };
Cheers! Did you also manage to make this component responsive on phones when including time?
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.