自动建议 renderInputComponent - 属性“onChange”的 inputProps 类型不兼容
Posted
技术标签:
【中文标题】自动建议 renderInputComponent - 属性“onChange”的 inputProps 类型不兼容【英文标题】:Autosuggest renderInputComponent - inputProps types of property 'onChange' are incompatible 【发布时间】:2020-08-30 06:56:15 【问题描述】:在将react-autosuggest
与自定义输入样式组件一起使用时,我遇到了这个 Typescript 错误。
属性“onChange”的类型不兼容。类型 '(event: FormEvent, params: ChangeEvent) => void' 不可分配给类型 '(event: ChangeEvent) => void'。
代码: (注意不完整,只是相关部分)
// styled.ts
export const Input = styled.input`
// styles
`;
// index.tsx
function renderInput(
inputProps: Autosuggest.InputProps<SuggestionSearch>,
placeholder: string
)
// --> error here
return <Input ...inputProps placeholder=placeholder />;
const MyComponent = () =>
const autosuggestRef = React.useRef<
Autosuggest<SuggestionSearch, SuggestionSearch>
>(null);
const onChange = (event: React.FormEvent, newValue : ChangeEvent) =>
setValue(newValue);
const inputProps =
value,
onChange,
onKeyPress: onEnterPress,
;
return (
<Autosuggest
ref=autosuggestRef
renderInputComponent=props => renderInput(props, placeholder)
inputProps=inputProps
// other props
/>
)
不确定如何解决此问题,因为 Autosuggest onChange 函数会覆盖基本输入 onChange 属性。
【问题讨论】:
【参考方案1】:我自己花了整晚的时间来解决这个问题。看来这是一个错误。这是InputProps
的签名:
interface InputProps<TSuggestion>
extends Omit<React.InputhtmlAttributes<any>, 'onChange' | 'onBlur'>
onChange(event: React.FormEvent<any>, params: ChangeEvent): void;
onBlur?(event: React.FocusEvent<any>, params?: BlurEvent<TSuggestion>): void;
value: string;
看来我们需要创建自己的Input
组件来接收这种类型的onChange
签名,或者将这个onChange 包装在标准的onChange 中。
所以,这是我的方法:
const renderInputComponent = (inputProps: InputProps<TSuggestion>): React.ReactNode =>
const onChangeHandler = (event: React.ChangeEvent<HTMLInputElement>): void =>
inputProps.onChange(event, newValue: event.target.value, method: 'type' );
;
return <Input ...inputProps onChange=onChangeHandler />;
两个潜在的错误:
请注意,返回的event
是React.ChangeEvent
,而不是React.FormEvent
。微小的差异,但如果您实际使用它并且对事件足够特别,它可能会在运行时出现问题。
返回的params: ChangeEvent
只占type
事件方法。如果你想要其他的,比如click、esc等等……你必须自己补充(例如通过onKeyUp
,然后调用`onChange(...method: 'esc')
根据文档:
注意:在使用 renderInputComponent 时,仍然需要指定通常的 inputProps。 Autosuggest 会将您提供的 inputProps 与可访问性所需的其他 props 合并(例如“aria-activedescendant”),并将合并后的 inputProps 传递给 renderInputComponent。
你不必这样做:
renderInputComponent=props => renderInput(props, placeholder)
只需将placeholder
直接传递给您的inputProps
,它就会在renderInputComponent
中直接返回给您。
const inputProps =
value,
onChange,
onKeyPress: onEnterPress,
placeholder: 'something!`
;
【讨论】:
【参考方案2】:我的问题是 renderInputComponent 上的 onChange() 不会触发 onSuggestionsFetchRequested。
如果我不使用自定义输入(通过 renderInputComponent),那么一切正常 - 触发 onSuggestionsFetchRequested 并显示建议列表。
主要组件:
const MySearchBox: FC<MySearchBoxProps> = (props) =>
// Autosuggest will pass through all these props to the input.
const inputProps =
placeholder: props.placeholder,
value: props.value,
onChange: props.onChange
;
return (
<Autosuggest
suggestions=props.suggestions
onSuggestionsFetchRequested=props.onSuggestionsFetechRequested
onSuggestionsClearRequested=props.onSuggestionsClearRequested
getSuggestionValue=props.getSuggestionValue
shouldRenderSuggestions=(value) => value.trim().length > 2
renderSuggestion=(item: ISuggestion) =>
<div className=classes.suggestionsList>`$item.text ($item.id)`</div>;
renderInputComponent=(ip: InputProps<ISuggestion>) =>
const params: InputProps<ISuggestion> =
...ip,
onChange: props.onChange
;
return renderInput(params);
inputProps=inputProps
/>
);
;
export MySearchBox ;
自定义输入组件:
import React, FC, ChangeEvent from 'react';
import SearchIcon from '@material-ui/icons/Search';
import useStyles from './searchInput.styles';
import Input from '@material-ui/core';
type SearchInputBoxProps =
loading?: boolean;
searchIconName: string;
minWidth?: number;
placeHolder?: string;
onChange?: (e: ChangeEvent, params: newValue: string; method: string ) => void;
;
const SearchInputBox: FC<SearchInputBoxProps> = (props) =>
const classes = useStyles();
return (
<div className=classes.root>
<div className=classes.searchIcon>
<SearchIcon />
</div>
<Input
placeholder=props.placeHolder
classes=
root: classes.inputContainer,
input: classes.inputBox
inputProps= 'aria-label': 'search'
onChange=(e) =>
const params: newValue: string; method: string =
newValue: e.target.value,
method: 'type'
;
console.log(`e: $JSON.stringify(params)`);
if (props.onChange) props.onChange(e, params);
//onMouseOut=(e) => alert(e.currentTarget.innerText)
/>
</div>
);
;
export SearchInputBox ;
渲染函数:
const renderInput = (inputProps: InputProps<ISuggestion>): React.ReactNode =>
return <SearchInputBox loading=false onChange=inputProps.onChange placeHolder=inputProps.placeholder searchIconName='search' ...inputProps.others />;
;
【讨论】:
【参考方案3】:我有同样的问题。
我只需要将 HTMLElement 转换为 HTMLInputElement 如下所示
const target = e.currentTarget as HTMLInputElement
然后,当你这样做时它工作正常
target.value
【讨论】:
以上是关于自动建议 renderInputComponent - 属性“onChange”的 inputProps 类型不兼容的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Selenium 从亚马逊上的自动建议中“点击”某些建议?