应用场景
输入框自动完成功能,如下图,当我们输入文字时,依据我们输入的文字,调用接口进行提示。
问题
当输入的是中文的时候,input框的onchange事件会随着我们按下键盘的每一次被不断的被触发。
解决方案
1.防抖和节流
可以减少接口的调用次数,但是不能准确的捕获到我们的输入内容。
2.通过input的compositionstart和compositionend监听中文输入的开始和结束
通过对输入中文时候的特殊处理,在恰当的时机触发事件。
实现代码
以下是对antd组件AutoComplete进行了二次封装
import React, { useState } from 'react';
import { Input, AutoComplete } from 'antd';
import PropTypes from 'prop-types';
const { Option } = AutoComplete;
const AotoComplete = React.forwardRef(
({ searchCallback, dataSource = [], onChange, value, selectCallback, fieldsLabel }, ref) => {
const [compositionFlag, setCompositionFlag] = useState(false);
const handleSelect = (val, option) => {
onChange && typeof onChange === 'function' && onChange(option.props.children);
selectCallback && typeof selectCallback === 'function' && selectCallback(val);
};
const handleCompositionstart = () => {
setCompositionFlag(true);
};
const handleCompositionend = (e) => {
setCompositionFlag(false);
searchCallback(e.target.value);
};
const handleInput = (e) => {
onChange && typeof onChange === 'function' && onChange(e.target.value);
if (!compositionFlag) {
searchCallback && typeof searchCallback === 'function' && searchCallback(e.target.value);
}
};
const options = dataSource.map((item) => (
<Option key={item[fieldsLabel.key]}>{item[fieldsLabel.val]}</Option>
));
return (
<AutoComplete
placeholder=""
dataSource={options}
onSelect={handleSelect}
defaultValue={value}
ref={ref}
>
<Input
onCompositionStart={handleCompositionstart}
onCompositionEnd={handleCompositionend}
onInput={handleInput}
/>
</AutoComplete>
);
},
);
export default AotoComplete;
AotoComplete.propTypes = {
dataSource: PropTypes.arrayOf(PropTypes.object).isRequired,
fieldsLabel: PropTypes.shape({
key: PropTypes.string,
val: PropTypes.string,
}).isRequired,
value: PropTypes.string,
searchCallback: PropTypes.func,
onChange: PropTypes.func,
selectCallback: PropTypes.func,
};
AotoComplete.defaultProps = {
searchCallback: null,
onChange: null,
selectCallback: null,
};