使用redux-form和react-select.creatable为什么模糊事件会清除输入?

时间:2018-02-24 21:55:48

标签: reactjs autocomplete redux-form react-select

我正在使用:

  • 反应15.6.2
  • redux-form 7.2.0
  • react-select 1.2.1

我还没有为此设置代码,但它很复杂。希望有人会从源头上看到这个问题。我可以做梦,可以吗?

我有redux-form显示invoice对象:

invoice = { client: { email: 'someguy@somewhere.com' } }

摘要:我使用react-select.creatable作为电子邮件下拉列表的自动填充组件。选择email会在client上设置invoice

typing and hitting enter creates and selects the new option

当我创建一个新的电子邮件地址并选择它时,然后模糊输入字段,输入值被清除。

enter image description here

client表单上的新invoice仍然在redux存储中正确设置,它只是从Field的输入值中清除。为什么呢?

  • 请注意我已根据其他答案手动调用Select中的input.onBlur(),其值正确。我认为这与创建新选项有关。

    //包含自定义自动完成组件的redux-form字段

    const clientOptions = clients.map(client =>({label:client.email,value:client})) const isValidNewOption =({label})=> email.REG_EMAIL.test(标签) const promptTextCreator =(label)=> (Send to ${label}) const newOptionCreator =({label,labelKey,valueKey})=> {   return {label:label,value:{email:label}} }

// RFReactSelect,一个反应选择的Creatable,可以作为一个能够创建新选项的自动完成

import React, { PropTypes } from 'react';
import Select from 'react-select';
import 'react-select/dist/react-select.css';

RFReactSelect.defaultProps = {
  multi: false,
  className: ""
};

RFReactSelect.propTypes = {
  input: PropTypes.shape({
    name: PropTypes.string.isRequired,

    onBlur: PropTypes.func.isRequired,
    onChange: PropTypes.func.isRequired,
    onFocus: PropTypes.func.isRequired,
  }).isRequired,
  options: PropTypes.array.isRequired,
  multi: PropTypes.bool,
  className: PropTypes.string,
  onNewOptionClick: PropTypes.func,
};

export default function RFReactSelect(props) {
  const { input , options, multi, className,
    newOptionCreator, promptTextCreator, isValidNewOption } = props
  const { name, value, onBlur, onChange, onFocus } = input;
  const transformedValue = transformValue(value, options, multi);

  return (
    <Select.Creatable
      className={className}
      isValidNewOption={isValidNewOption}
      name={name}
      multi={multi}
      newOptionCreator={newOptionCreator}
      onSelectResetsInput={false}
      onBlurResetsInput={false}
      options={options}
      onChange={multi
        ? multiChangeHandler(onChange)
        : singleChangeHandler(onChange)
      }
      onBlur={() => onBlur(value)}
      onFocus={onFocus}
      promptTextCreator={promptTextCreator}
      value={transformedValue}
      valueKey='value'
    />
  );
}

/**
 * onChange from Redux Form Field has to be called explicity.
 */
function singleChangeHandler(func) {
  return function handleSingleChange(value) {
    func(value ? value.value : '');
  };
}

/**
 * onBlur from Redux Form Field has to be called explicity.
 */
function multiChangeHandler(func) {
  return function handleMultiHandler(values) {
    func(values.map(value => value.value));
  };
}

/**
 * For single select, Redux Form keeps the value as a string, while React Select
 * wants the value in the form { value: "grape", label: "Grape" }
 *
 * * For multi select, Redux Form keeps the value as array of strings, while React Select
 * wants the array of values in the form [{ value: "grape", label: "Grape" }]
 */
function transformValue(value, options, multi) {
  if (multi && typeof value === 'string') return [];

  const filteredOptions = options.filter(option => {
    return multi
      ? value.indexOf(option.value) !== -1
      : option.value === value;
  });

  return multi ? filteredOptions : filteredOptions[0];
}

1 个答案:

答案 0 :(得分:0)

annnnd我解决了它。问题是你必须跟踪本地状态下新创建的选项,并将它们与组件的props.options连接起来,否则新的选项会在重新渲染时丢失。因此传递回value的{​​{1}}的{​​{1}}为空。这是来源:

onBlur