首页 > 解决方案 > 使用 DownShift 中的 useComboBox 和 react-hook-form

问题描述

我正在尝试将 DownShift 中的 useComboBox 与 react-hook-form 一起使用,并且输入的值始终未定义。我从这个开始:https ://codesandbox.io/s/react-hook-form-controller-079xx?file=/src/DonwShift.js

并将 DownShift.js 组件替换为:https ://codesandbox.io/s/usecombobox-usage-1fs67?file=/src/index.js:168-438

除非我提交未定义的值,否则一切正常。设置值时我缺少什么?

<form className="card" onSubmit={handleSubmit(handleShare)}>
  <div className="body">
    <Controller
      as={Autocomplete}
      control={control}
      name="recipient"
      items={userList}
    />
    <button
      className="secondaryActionBtn inputBtn"
      type="submit"
      enabled={String(formState.dirty)}
    >
      <FontAwesomeIcon icon={faPlus} />
    </button>
    {errors.lastname && 'Feed Name is required.'}
  </div>
  <footer></footer>
</form>

import React, { memo, useState } from 'react';
import PropTypes from 'prop-types';
import { useCombobox } from 'downshift';

const menuStyles = {
  maxHeight: '180px',
  overflowY: 'auto',
  width: '135px',
  margin: 0,
  borderTop: 0,
  background: 'white',
  position: 'absolute',
  zIndex: 1000,
  listStyle: 'none',
  padding: 0,
  left: '135px'
};

const comboboxStyles = { display: 'inline-block', marginLeft: '5px' };

function Item({ isHighlighted, getItemProps, item, index }) {
  return (
    <li
      style={isHighlighted ? { backgroundColor: '#bde4ff' } : {}}
      key={`${item}${index}`}
      {...getItemProps({ item, index })}
    >
      {item}
    </li>
  );
}

Item = memo(Item);

const Autocomplete = ({ items }) => {
  const [inputItems, setInputItems] = useState(items);
  const {
    isOpen,
    getToggleButtonProps,
    getLabelProps,
    getMenuProps,
    getInputProps,
    getComboboxProps,
    highlightedIndex,
    getItemProps
  } = useCombobox({
    items: inputItems,
    onInputValueChange: ({ inputValue }) => {
      setInputItems(
        items.filter(item =>
          item.toLowerCase().includes(inputValue.toLowerCase())
        )
      );
    }
  });

  return (
    <div>
      <label htmlFor="recipient" {...getLabelProps()}>
        Choose an element:
      </label>
      <div style={comboboxStyles} {...getComboboxProps()}>
        <input name="recipient" {...getInputProps()} id="recipient" />
        <button {...getToggleButtonProps()} aria-label="toggle menu">
          &#8595;
        </button>
      </div>
      <ul {...getMenuProps()} style={menuStyles}>
        {isOpen &&
          inputItems.map((item, index) => (
            <Item
              key={item}
              isHighlighted={highlightedIndex === index}
              getItemProps={getItemProps}
              item={item}
              index={index}
            />
          ))}
      </ul>
    </div>
  );
};

Autocomplete.propTypes = {
  list: PropTypes.array
};

export default Autocomplete;

标签: react-hook-formdownshift

解决方案


对于其他陷入困境的人来说,这就是我解决它的方法。react-hook-form 中的 Controller 将 onChange 作为 prop 注入到组件中。所以我在 useCombobox 钩子中设置了 onSelectedItemChange 属性,以将其值传递给 onChange。像这样:

const {
    isOpen,
    getToggleButtonProps,
    getLabelProps,
    getMenuProps,
    getInputProps,
    getComboboxProps,
    highlightedIndex,
    getItemProps
  } = useCombobox({
    items: inputItems,
    onSelectedItemChange: ({ inputValue }) => onChange(inputValue),
    onInputValueChange: ({ inputValue }) => {
      setInputItems(
        items.filter(item =>
          item.toLowerCase().includes(inputValue.toLowerCase())
        )
      );
    }
  });

推荐阅读