我创建了该自定义钩子
// useDropdown.ts
function useDropdown(defaultState: number, options: number[]) {
const [state, setState] = useState(defaultState);
function Dropdown({ name }: { name: string }) {
return (
<>
<select
name={name}
value={state}
onChange={(e) => setState(Number(e.target.value))}
onBlur={(e) => setState(Number(e.target.value))}
disabled={options.length === 0}
>
{options.map((item) => (
<option key={item} value={item}>
{item}h
</option>
))}
</select>
</>
);
}
return [state, Dropdown, setState];
}
export default useDropdown;
// HourPicker.ts
const HourPicker = ({ day, label }: HourPickerProps) => {
const [checked, changeChecked] = useState(
day.startHour && day.endHour ? true : false
);
const [startHour, StartHourDropdown] = useDropdown(day.startHour || 9, hours);
const [endHour, EndHourDropdown] = useDropdown(day.endHour || 18, hours);
function useChecked() {
changeChecked(!checked);
}
return (
<HourPickerContainer checked={checked}>
<p>
De <StartHourDropdown name={`${label}-start`} /> à{" "}
<EndHourDropdown name={`${label}-end`} />
</p>
</HourPickerContainer>
);
};
当我使用由挂钩返回的组件 Dropdown 时,出现此错误:
JSX element type 'StartHourDropdown' does not have any construct or call signatures.
此组件运行良好,但是每次调用该组件时,如果不编写ts忽略就无法编译。
感谢您的帮助
答案 0 :(得分:0)
这里的问题是构造函数和实例之间的混乱。
无论何时我们在React中编写组件:
class Greeter extends React.Component<any, any> {
render() {
return <div>Hello, {this.props.hello}</div>;
}
}
您以这种方式使用它:
return <Greeter hello='world' />;
不是这样:
let Greet = new Greeter();
return <Greet whoToGreet='world' />;
在第一个示例中,我们传递了Greeter(组件的构造函数)。那是准确的用法。在第二个示例中,我们传递了一个Greeter实例。这是不正确的,并且会在运行时产生错误,例如“对象不是函数”。
此代码存在问题
function renderGreeting(Elem: React.Component<any, any>) {
return <span>Hello, <Elem />!</span>;
}
是它期待一个React.Component实例。我们想要的是一个为React.Component构造函数的函数:
function renderGreeting(Elem: new() => React.Component<any, any>) {
return <span>Hello, <Elem />!</span>;
}
或类似地:
function renderGreeting(Elem: typeof React.Component) {
return <span>Hello, <Elem />!</span>;
}