dan*_*nvk 6 typescript reactjs material-ui
我在 React 中使用 TypeScript,并使用箭头函数作为Material UI<Select>组件的回调:
import React from 'react';
import MenuItem from '@material-ui/core/MenuItem';
import Select from '@material-ui/core/Select';
interface Props {
value: string;
onSelect: (value: string) => void;
}
function MySelector(props: Props) {
return (
<Select
value={props.value}
onChange={e => props.onSelect(e.value as string)}
>
<MenuItem value="a">A</MenuItem>
<MenuItem value="b">B</MenuItem>
<MenuItem value="c">C</MenuItem>
</Select>
)
}
Run Code Online (Sandbox Code Playgroud)
为了避免每次MySelector渲染时都传递一个新函数,我想使用useCallbackhook。虽然直接重构在运行时有效,但由于any事件参数上的隐式错误,它无法进行类型检查e:
function MySelector(props: Props) {
const handleChange = React.useCallback(
e => props.onSelect(e.value as string),
// ~ e implicitly has an any type
[props.onSelect]
);
return (
<Select
value={props.value}
onChange={handleChange}
>
{ /* ... menu items ... */ }
</Select>
)
}
Run Code Online (Sandbox Code Playgroud)
将鼠标悬停e在原始符号上显示其类型为
React.ChangeEvent<{
name?: string | undefined;
value: unknown;
}>
Run Code Online (Sandbox Code Playgroud)
这是一口,但要修复我必须输入的错误:
const handleChange = React.useCallback(
(
e: React.ChangeEvent<{
name?: string | undefined;
value: unknown;
}>,
) => props.onSelect(e.value as string),
[props.onSelect],
);
Run Code Online (Sandbox Code Playgroud)
我可以吃蛋糕也吃吗?我可以使用useCallback钩子并仍然从上下文中获取事件参数的类型吗?
以下是您如何通过常规反应来做到这一点。我一步步描述了每个操作,以便您可以尝试重现它们:
import React, { useCallback } from "react";
import "./App.css";
// First we get the DOM Attributes for the Element we care about:
// => `React.DOMAttributes<HTMLSelectElement>`
// Then we access the field we need
// => `...["onChange"]`
// Then we remove the "undefined" union
// => `NonNullable<...>`
// which gives you:
type OnChangeCallback = NonNullable<
React.DOMAttributes<HTMLSelectElement>["onChange"]
>;
const App: React.FC = () => {
// we use this type in the `useCallback` definition directly:
const onChange = useCallback<OnChangeCallback>((e) => {
console.log(e);
}, []);
return <select className="main" onChange={onChange}></select>;
};
export default App;
Run Code Online (Sandbox Code Playgroud)
它应该很容易适应您的组件库。
变成通用的,因此更容易导入和使用:
export type On<T, V extends keyof React.DOMAttributes<T>> = NonNullable<
React.DOMAttributes<T>[V]
>;
// Use it with:
const myCallback: On<HTMLDivElement, "onMouseMove"> = (e) => {};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
546 次 |
| 最近记录: |