我想使用TypeScript在 React 中创建一个自定义组件,它本质上是一个具有自动完成/搜索功能的组合框,连接到它自己的远程存储。我想做的是发送一个"onSelect"事件,以便我可以在应用程序中使用该组件的任何地方接收所选项目。
使用远程存储进行自动完成/搜索操作很容易,但是 React 组件的东西让我感到困惑。我仍然在学习两者,所以也许我在爬行之前试图走路,但我不想在我知道应该有可能实现这个更优雅的结果时开始制造混乱。我只需要找到某种指南,但到目前为止我还没有找到。
以下是我想要实现的目标:
<MyCombobox onSelect={handleSelect} />
handleSelect 函数将在整个应用程序中使用,只要我需要使用 MyCombobox 组件。当然,该函数需要接受一个参数(这就是目前在 TS 中让我难倒的原因)。
一种可能的解决方案如下
import * as React from "react";
import { render } from "react-dom";
interface MyComboProps {
// Here props from parent should be defined
}
interface MyComboState {
ValuesToShow: string[];
SearchValue: string;
}
class StringSearchMenu extends React.Component<MyComboProps, MyComboState> {
constructor(p: MyComboProps) {
super(p);
this.state = {
ValuesToShow: [],
SearchValue: ""
};
}
protected selectString(event: React.ChangeEvent<HTMLInputElement>): void {
let value = event.target.value;
if (value === "") this.setState({ ValuesToShow: [] });
else {
/* here you can put fetch logic. I use static array as example */
let possibleValues = ["Green", "Red", "Blue", "Yellow", "Black"];
this.setState({
ValuesToShow: possibleValues.filter(f => f.indexOf(value) > -1)
});
}
}
render() {
return (
<div>
Enter value to search {" "}
<input onChange={this.selectString.bind(this)} />
<div>
{this.state.ValuesToShow.map(v => (
<div>{v}</div>
))}
</div>
</div>
);
}
}
工作示例在这里
从我今天早上所做的所有谷歌搜索中,我设法拼凑出一些有用的东西(来自大量来源):
App.tsx:
import React from 'react';
import './App.css';
import MyCombobox from './MyCombobox';
class App extends React.Component {
receiveSomething(something: string) {
alert('Something: ' + something);
}
render() {
return (
<div>
<MyCombobox receiveSomething={this.receiveSomething} defaultValue="qwerty" />
</div>
);
}
}
export default App;
MyCombobox.tsx:
import React from 'react';
export interface IMyCombobox {
defaultValue: string,
receiveSomething:(name:string) => void
}
class MyCombobox extends React.PureComponent<IMyCombobox, any> {
state = {
something: this.props.defaultValue
}
sendSomething() {
this.props.receiveSomething(this.state.something);
}
handleChange = (event: any) : void => {
this.setState({
something: event.target.value
});
}
render() {
return (
<div>
<input
type='text'
maxLength={20}
value={this.state.something}
onChange={this.handleChange} />
<input
type='button'
value='Send Something'
onClick={this.sendSomething.bind(this)} />
</div>
)
}
}
export default MyCombobox;