将 Typescript 类型添加到 react-select onChange 函数 [英] Add Typescript types to react-select onChange function
问题描述
我正在我的应用程序中使用来自 React Select 的 CreatableSelect
组件但我在添加 Typescript 类型时遇到问题.
I am using the CreatableSelect
component from React Select in my application but I am having trouble adding Typescript types.
我想要做的就是使用正确的类型从 handleChange = (value: any)
更改 any
.我使用了这个 const handleChange = (value: { label: any; value: any }[]) =>{
但它不起作用.
All I want to do is to change any
from handleChange = (value: any)
with the right types. I used this const handleChange = (value: { label: any; value: any }[]) => {
but it does not work.
如何将 any
类型更改为正确的类型?
How can I change any
type to the right type?
演示:https://codesandbox.io/s/codesandboxer-example-forked-9tsfp?file=/example.js
export default class CreatableInputOnly extends Component<*, State> {
state = {
inputValue: "",
value: []
};
handleChange = (value: any) => {
console.log(value, "test");
this.setState({ value });
};
handleInputChange = (inputValue: string) => {
this.setState({ inputValue });
};
handleKeyDown = (event: SyntheticKeyboardEvent<HTMLElement>) => {
const { inputValue, value } = this.state;
if (!inputValue) return;
switch (event.key) {
case "Enter":
case "Tab":
console.group("Value Added");
console.log(value);
console.groupEnd();
this.setState({
inputValue: "",
value: [...value, createOption(inputValue)]
});
event.preventDefault();
}
};
render() {
const { inputValue, value } = this.state;
return (
<CreatableSelect
components={components}
inputValue={inputValue}
isClearable
isMulti
menuIsOpen={false}
onChange={this.handleChange}
onInputChange={this.handleInputChange}
onKeyDown={this.handleKeyDown}
placeholder="Type something and press enter..."
value={value}
/>
);
}
}
推荐答案
具体类型取决于泛型类型参数 OptionType
.OptionType
的默认类型是 { label: string;值:字符串 }
您正在使用的类型.
The specific types depend on a generic type parameter OptionType
. The default type for OptionType
is the { label: string; value: string }
type which you are using.
我认为您遇到的问题是由于您环境中的类型包不正确/过时造成的.
在 新 CodeSandbox,我安装了@types/react-select
,onChange
函数的定义是:
In a new CodeSandbox, where I installed @types/react-select
, the definition for the onChange
function is:
onChange?: (value: ValueType<OptionType, IsMulti>, action: ActionMeta<OptionType>) => void;
这个 ValueType
实用程序类型基本上是说,在单个选择上,您有一个选项或 null
,在多个选择上,您有一个 array
选项.
This ValueType
utility type basically says that on a single select you have either an option or null
and on on multiple select you have an array
of options.
export type ValueType<OptionType extends OptionTypeBase, IsMulti extends boolean> = IsMulti extends true
? OptionsType<OptionType>
: OptionType | null;
export type OptionsType<OptionType extends OptionTypeBase> = ReadonlyArray<OptionType>;
我不确定您链接的沙箱如何对其类型进行排队,因为 @types/react-select
包未包含在 package.json
中.但是如果我转到定义"我从 /sandbox/node_modules/@types/react-select/src
文件中得到一个定义.这些是我看到的类型:
I'm not sure how your linked sandbox is enqueing its types because the @types/react-select
package is not included in the package.json
. But if I "Go To Definition" I get a definition from a /sandbox/node_modules/@types/react-select/src
file. These are the types that I see:
onChange?: (value: ValueType<OptionType>, action: ActionMeta) => void;
export type ValueType<OptionType extends OptionTypeBase> = OptionType | OptionsType<OptionType> | null | undefined;
export type OptionsType<OptionType extends OptionTypeBase> = ReadonlyArray<OptionType>;
那么有什么区别?
在第一种情况下,我们知道由于您有多项选择,您将始终收到一系列选项.
In the first case, we know that since you have a multi-select you will always receive an array of options.
在第二种情况下没有 IsMulti
标志,因此类型声明您可以接收数组或单个选项(或 null
或 undefined代码>).您的
handleChange
函数只能处理一个数组,因此它不能用作 onChange
处理程序,因为它无法处理它可能收到的所有可能的参数.
In the second case there is no IsMulti
flag, so the types state that you could receive an array or a single option (or null
or undefined
). Your handleChange
function can only handle an array, so it can't be used as an onChange
handler since it can't handle all of the possible arguments that it might receive.
使用正确的包类型,您之前尝试的几乎是正确的.唯一的问题是数组是readonly
,所以我们必须确保我们可以在处理程序和状态中接受ReadonlyArray
.
With the correct package types, what you tried before is almost correct. The only issue is that the array is readonly
, so we have to make sure that we can accept a ReadonlyArray
in both the handler and the state.
仅供参考,这些函数没有在我直觉上期望的地方被调用.handleChange
在删除标签时调用,但在按 Enter 添加新标签时不会调用.因此,您需要查看文档和/或尝试各种回调.有 六个道具CreatableSelect
-- 两个设置和四个回调.
FYI these functions aren't being called where I would intuitively expect. handleChange
is called when removing a tag but not when adding a new one by pressing enter. So you'll want to check out the docs and/or play with the various callbacks. There are six props which are only on CreatableSelect
-- two settings and four callbacks.
使用 @types/react-select
4.0.13 和 react-select
4.3.0,这应该可以修复所有 Typescript 错误:
This should fix all of your Typescript errors, using @types/react-select
4.0.13 and react-select
4.3.0:
import React, { Component } from "react";
import CreatableSelect from "react-select/creatable";
import { ActionMeta, InputActionMeta } from "react-select";
const components = {
DropdownIndicator: null
};
const createOption = (label: string) => ({
label,
value: label
});
type MyOption = ReturnType<typeof createOption>;
// or type MyOption = { label: string; value: string; }
interface MyState {
inputValue: string;
value: ReadonlyArray<MyOption>;
}
interface MyProps {
// are there any?
}
export default class CreatableInputOnly extends Component<MyProps, MyState> {
state: MyState = {
inputValue: "",
value: []
};
handleChange = (
value: ReadonlyArray<MyOption>,
meta: ActionMeta<MyOption>
) => {
console.log("value", value, "meta", meta);
this.setState({ value });
};
handleInputChange = (inputValue: string, meta: InputActionMeta) => {
this.setState({ inputValue });
};
handleKeyDown = (event: React.KeyboardEvent<HTMLElement>) => {
const { inputValue, value } = this.state;
if (!inputValue) return;
switch (event.key) {
case "Enter":
case "Tab":
console.group("Value Added");
console.log(value);
console.groupEnd();
this.setState({
inputValue: "",
value: [...value, createOption(inputValue)]
});
event.preventDefault();
}
};
render() {
const { inputValue, value } = this.state;
return (
<CreatableSelect
components={components}
inputValue={inputValue}
isClearable
isMulti
menuIsOpen={false}
onChange={this.handleChange}
onInputChange={this.handleInputChange}
onKeyDown={this.handleKeyDown}
placeholder="Type something and press enter..."
value={value}
/>
);
}
}
这篇关于将 Typescript 类型添加到 react-select onChange 函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!