【问题标题】:Get value of highlighted option in React-Select获取 React-Select 中突出显示的选项的值
【发布时间】:2019-09-27 01:30:22
【问题描述】:

我将 react-select v2 与异步选择组件一起使用。

        <AsyncSelect
            cacheOptions
            components={{ Option }}
            loadOptions={this.getSearchItems}
            onInputChange={this.handleInputChange}
            placeholder="Search..."
            onKeyDown={this._handleKeyPress}
        />

如何访问因使用键盘上的向下键或鼠标悬停而突出显示的选项的值?

我想根据 highlighted 选项触发重定向或 setState。 onKeyDown 仅以event.target.value 的形式发送输入值

这是 Nordstrom 网站上的一个示例:

【问题讨论】:

    标签: reactjs react-select


    【解决方案1】:

    我认为仅使用 react-select api 是不可能的,但您可以创建自己的 HOC,将这个功能添加到 AsyncSelect。

    class MyAsyncSelect extends React.Component {
    
      /* Select component reference can be used to get currently focused option */
      getFocusedOption() {
        return this.ref.select.select.state.focusedOption;
      }
    
      /* we'll store lastFocusedOption as instance variable (no reason to use state) */
      componentDidMount() {
        this.lastFocusedOption = this.getFocusedOption();
      }
    
      /* Select component reference can be used to check if menu is opened */
      isMenuOpen() {
        return this.ref.select.state.menuIsOpen;
      }
    
      /* This function will be called after each user interaction (click, keydown, mousemove).
         If menu is opened and focused value has been changed we will call onFocusedOptionChanged 
         function passed to this component using props. We do it asynchronously because onKeyDown
         event is fired before the focused option has been changed.
      */
      onUserInteracted = () => {
        Promise.resolve().then(() => {
          const focusedOption = this.getFocusedOption();
          if (this.isMenuOpen() && this.lastFocusedOption !== focusedOption) {
            this.lastFocusedOption = focusedOption;
            this.props.onFocusedOptionChanged(focusedOption);
          }
        });
      }
    
      /* in render we're setting onUserInteracted method as callback to different user interactions */
      render () {
        return (
          <div onMouseMove={this.onUserInteracted} onClick={this.onUserInteracted}> 
            <AsyncSelect 
              {...this.props} 
              ref={ref => this.ref = ref}
              onKeyDown={this.onUserInteracted}
            />
          </div>
        );
      }
    }
    

    然后您可以像 AsyncSelect 一样使用此自定义组件,但能够对焦点选项更改做出反应:

    class App extends React.Component {
    
      onFocusedOptionChanged = focusedValue => console.log(focusedValue) 
    
      render() {
        return (
          <div>
            <MyAsyncSelect
              cacheOptions
              loadOptions={loadOptions}
              defaultOptions
              onInputChange={this.handleInputChange}
              onFocusedOptionChanged={this.onFocusedOptionChanged}
            />
          </div>
        );
      }
    }
    

    工作演示:https://stackblitz.com/edit/react-z7izuy

    编辑: 带有附加属性onOptionSelected 的版本,当用户选择选项时将调用该属性。 https://stackblitz.com/edit/react-wpljbl

    【讨论】:

    • 不错!我仍然不清楚如何只触发event.key === 'enter'。我把那张支票放在哪里?截至目前,任何鼠标悬停或按键都会触发我的功能。
    • 我不确定我是否理解你的意思,因为在你的问题中你想access the value of an option that is highlighted as a result of using the down key on keyboard or hovering with a mouse?。也许只是告诉我你想对哪些事件做出反应,以及当这些事件发生时应该传递哪些数据。
    • 抱歉,不清楚。每个选项都有自己的链接,包括输入值(我手动将其传递给选项),因此当用户通过单击选项或在焦点选项上按“输入”来选择选项时,我想重定向然后到一个独特的选项链接。
    • 换句话说,onKeyDown 应该接受当前的焦点选项,而不是当前的输入值。
    • 相同的功能。我能够通过传递自定义选项组件并包装在 标记中来实现。
    【解决方案2】:

    我通过使用 onChange 道具解决了这个问题。

    1. UI/选择组件

        class CustomSelect extends React.PureComponent<IProps> {
          handleChange = (selectedOption: any) => {
          if (this.props.onSelect) {
              this.props.onSelect(selectedOption);
          }
        };
      
        render() {
          const { data } = this.props;
          return (
            <Select
              onChange={this.handleChange}
              options={data}
            />
          );
        }
      

      }

      1. 我将 CustomSelect 与 react-router 4 一起使用的父级(我可以访问 withRouter)。

        class SelectParent extends React.Component<IProps> {
          onSelect = (option: any) => {
          const id = option.value;
          const { history } = this.props;
          history.push(`/category/${id}`);
        };
        
        render() {
          const { data } = this.props;
          return (
            <Select
            data={data}
            onSelect={this.onSelect}
          />);
          }
        }
        
        export default withRouter<any>(SelectParent);
        

    【讨论】:

      【解决方案3】:

      这对我有用。

       handleOnChange = (value, { action }) => {
          if (action === 'select-option') {
            // do something
          }
        };
      
      
       render() {
         return (
           <Select onChange={this.handleOnChange} ... />
         )
       }
      

      【讨论】:

        猜你喜欢
        • 2021-05-23
        • 1970-01-01
        • 1970-01-01
        • 2018-03-23
        • 1970-01-01
        • 1970-01-01
        • 2021-11-28
        • 1970-01-01
        • 2018-01-18
        相关资源
        最近更新 更多