0

工作沙箱是https://codesandbox.io/s/react-day-picker-base-h9fv6

我一直在尝试实现一个简单的日期选择器输入,您可以在输入字段中输入日期并在选择器中选择。

问题是当我使用自定义输入 <DayPickerInput component ={CustomInput}.../>时,使用选择器时输入会失去焦点。如果没有自定义输入,这不会发生。在文档中它说

“如果要在用户选择一天时保持焦点,组件类必须有焦点方法。”

但是我不确定我应该如何实现这一点。

4

2 回答 2

2

如果您需要具有焦点方法的自定义组件,我认为您需要使用类组件和refs

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}/>
  }
}
于 2019-09-26T09:46:38.237 回答
0

我使用“ react-text-mask ”库中的 MaskedInput 组件,以及来自“ react-day- picker”的“具有两个输入的日期范围选择器”的自定义覆盖组件

自定义覆盖和输入:

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,
   }}
   

主要问题的解决方案存在问题。如果我们不点击日期选择器中的日期(在标题、月份导航或其他地方),他的输入就会失去焦点。我的代码有助于解决它

于 2021-03-22T23:08:52.503 回答