工作沙箱已 https://codesandbox.io/s/react-day-picker-base-h9fv6
我一直在尝试实现一个简单的日期选择器输入,您可以在输入字段中输入日期并在选择器中进行选择。
问题是当我使用自定义输入时,<DayPickerInput component ={CustomInput}.../>
,当使用选取器时,输入会失去焦点。如果没有自定义输入,这不会发生。在文档中它说
"如果你想在用户选择一天时保持焦点,组件类必须有一个焦点方法。
但是,我不确定我应该如何实现这一点。
如果您需要带有 focus 方法的自定义组件,我认为您需要使用类组件,并引用:
class Input extends React.Component {
constructor(props) {
super(props);
this.inputRef = React.createRef();
}
focus() {
this.inputRef.current.focus();
}
render() {
return <input {...this.props} ref={this.inputRef}/>
}
}
我使用">react-text-mask"库中的 MaskedInput 组件,以及来自">反应日选择器"的"具有两个输入的日期范围选择器"的自定义覆盖组件。
自定义叠加和输入:
const renderMaskedInput = (_props, _ref) => {
return (
<MaskedInput
mask={getLocaleMask}
showMask
ref={_ref}
type="text"
render={(ref, inputProps) => <input ref={ref} {...inputProps} />}
{..._props}
/>
);};
<DayPickerInput
component={_props => renderMaskedInput(_props, startInputRef)}
overlayComponent={_props => (
<Popper
open={Boolean(startAnchorEl)}
anchorEl={startAnchorEl}
style={{ zIndex: 10000 }}
>
<div {..._props} className={customOverlayWrapper}>
<div className={customOverlay}>{_props.children}</div>
</div>
</Popper>
)}
我的问题是在打开或单击自定义叠加层时从选择器输入中失去焦点,并且">keepFocus"道具不适用于自定义输入。因此,单击背景后会导致关闭叠加层的问题,因为叠加层仅通过输入的"onBlur"关闭。
只是硬设置专注于onClick或其他东西的输入不起作用。我的解决方案是在自定义覆盖打开时更改输入引用后在 useEffect 中设置焦点,但这还不够,因为单击叠加层后焦点丢失,所以我们只是在DayPicker的 3 个处理程序之后将焦点设置为输入:onFocus、onMonthChange、onCaptionChange(参见代码沙箱示例(。
使用 Popper 作为 DayPickerInput 的自定义叠加解决了在屏幕自由区域中渲染叠加的问题(叠加的自动定位(。此外,Popper与Portal配合使用,它解决了渲染叠加的许多问题。
完整代码:https://codesandbox.io/s/optimistic-glitter-c77gb
简短版本:
const focusStartInput = () => {
startInputRef.current.inputElement.focus();
}
useEffect(() => {
// used because 'keepFocus' prop from the library does not work with the custom
// overlay or with the react-text-mask input
if (startAnchorEl) {
// if the start picker overlay is open
focusStartInput(); // input loses focus after overlay opening,
// so just reset focus
}
if (endAnchorEl) {
// if the end picker overlay is open
focusEndInput(); // input loses focus after overlay opening, so just reset focus
}
}, [startAnchorEl, endAnchorEl]);
<DayPickerInput
dayPickerProps={{
onMonthChange: focusStartInput,
onFocus: focusStartInput,
onCaptionClick: focusStartInput,
}}
主要问题的解决方案存在问题。如果我们不在日期选择器中单击日期(在标题、月份导航或其他地方(,他的输入就会失去焦点。我的代码有助于解决它。