本来新出的hook应该是个好用的东西,但是我在组件中使用没有任何问题,项目去引用这组件时却报了个:
Invalid hook call. Hooks can only be called inside of the body of a function component.
首先判定是不是版本问题,把组件和项目都重安了一遍react的包,而且都是同一个版本,还报这个错……
算了,不浪费时间找问题了,干脆花了点时间把组件里用useState的地方换回原来的写法得了。
于是:
import React, { useState } from 'react'
import { Button, Divider, InputGroup } from '@blueprintjs/core';
import { DateInput } from "@blueprintjs/datetime";
import '@blueprintjs/datetime/lib/css/blueprint-datetime.css';
import subMonths from 'date-fns/sub_months';
import { handleFormat, localeUtils } from '../utils/localeFn';
export interface IProps {
isSearching: boolean;
handleSearch: (text: string, startTime: string, endTime: string) => void;
}
export function CommonSearchPane(props: any) {
const [ text, setText ] = useState('');
const [ startTime, setStartTime ] = useState(handleFormat(subMonths(new Date(), 2)));
const [ endTime, setEndTime ] = useState(handleFormat(new Date()));
// const [ isSearch, setIsSearch ] = useState(false);
// 人员姓名输入
function handleInputChange(evt: React.ChangeEvent<HTMLInputElement>) {
const target = evt.target;
const value = target.value;
setText(value);
}
function handleParse(str: string) {
return new Date(str);
}
// 改变开始时间
function handleStartChange(selectedDate: Date) {
if (selectedDate !== null) {
setStartTime(handleFormat(selectedDate));
} else {
setStartTime(handleFormat(new Date()))
}
}
// 改结束始时间
function handleEndChange(selectedDate: Date) {
if (selectedDate !== null) {
setEndTime(handleFormat(selectedDate));
} else {
setEndTime(handleFormat(new Date()));
}
}
return (
<div className='common-search-div'>
<div className='line'>
<div className='title'>人员姓名:</div>
<div className='input'>
<InputGroup placeholder='输入姓名' value={text} onChange={handleInputChange} />
</div>
</div>
<div className='line'>
<div className='title'>开始时间:</div>
<div className='input'>
<DateInput
formatDate={handleFormat}
parseDate={handleParse}
timePrecision="second"
showActionsBar={true}
clearButtonText='取消'
todayButtonText='今天'
popoverProps={{position: 'right'}}
dayPickerProps={{ locale: 'zh', localeUtils }}
onChange={handleStartChange}
value={handleParse(startTime)}
/>
</div>
</div>
<div className='line'>
<div className='title'>结束时间:</div>
<div className='input'>
<DateInput
formatDate={handleFormat}
parseDate={handleParse}
timePrecision="second"
showActionsBar={true}
clearButtonText='取消'
todayButtonText='今天'
popoverProps={{position: 'right'}}
dayPickerProps={{ locale: 'zh', localeUtils }}
onChange={handleEndChange}
value={handleParse(endTime)}
/>
</div>
</div>
<div className='botton'>
<Button loading={props.isSearching ? true : false} fill={true} text='查询' intent='primary' onClick={props.handleSearch(text, startTime, endTime)} />
</div>
<Divider />
</div>
);
}
改成了:
import React from 'react'
import { Button, Divider, InputGroup } from '@blueprintjs/core';
import { DateInput } from "@blueprintjs/datetime";
import '@blueprintjs/datetime/lib/css/blueprint-datetime.css';
import subMonths from 'date-fns/sub_months';
import { handleFormat, localeUtils } from '../utils/localeFn';
export interface IProps {
isSearching: boolean;
handleSearch: (text: string, startTime: string, endTime: string) => void;
}
export interface IState {
text: string;
startTime: string;
endTime: string;
}
export class CommonSearchPane extends React.PureComponent<IProps, IState> {
constructor(props: IProps) {
super(props);
this.state = {
endTime: handleFormat(new Date()),
startTime: handleFormat(subMonths(new Date(), 2)),
text: '',
};
}
public render(){
const { text, startTime, endTime } = this.state;
const { isSearching } = this.props;
return (
<div className='common-search-div'>
<div className='line'>
<div className='title'>人员姓名:</div>
<div className='input'>
<InputGroup placeholder='输入姓名' value={text} onChange={this.handleInputChange} />
</div>
</div>
<div className='line'>
<div className='title'>开始时间:</div>
<div className='input'>
<DateInput
formatDate={handleFormat}
parseDate={this.handleParse}
timePrecision="second"
showActionsBar={true}
clearButtonText='取消'
todayButtonText='今天'
popoverProps={{position: 'right'}}
dayPickerProps={{ locale: 'zh', localeUtils }}
onChange={this.handleStartChange}
value={this.handleParse(startTime)}
/>
</div>
</div>
<div className='line'>
<div className='title'>结束时间:</div>
<div className='input'>
<DateInput
formatDate={handleFormat}
parseDate={this.handleParse}
timePrecision="second"
showActionsBar={true}
clearButtonText='取消'
todayButtonText='今天'
popoverProps={{position: 'right'}}
dayPickerProps={{ locale: 'zh', localeUtils }}
onChange={this.handleEndChange}
value={this.handleParse(endTime)}
/>
</div>
</div>
<div className='botton'>
<Button loading={isSearching ? true : false} fill={true} text='查询' intent='primary' onClick={this.handleSearch(text, startTime, endTime)} />
</div>
<Divider />
</div>
);
}
// 搜索
private handleSearch = (text: string, startTime: string, endTime: string) => {
return () => {
this.props.handleSearch(text, startTime, endTime);
}
}
// 人员姓名输入
private handleInputChange = (evt: React.ChangeEvent<HTMLInputElement>) => {
const target = evt.target;
const value = target.value;
this.setState({text: value});
}
private handleParse = (str: string) => {
return new Date(str);
}
// 改变开始时间
private handleStartChange = (selectedDate: Date) => {
if (selectedDate !== null) {
this.setState({startTime: handleFormat(selectedDate)});
} else {
this.setState({startTime: handleFormat(new Date())});
}
}
// 改结束始时间
private handleEndChange = (selectedDate: Date) => {
if (selectedDate !== null) {
this.setState({endTime: handleFormat(selectedDate)});
} else {
this.setState({endTime: handleFormat(new Date())});
}
}
}
或许我对hook的有点理解还不深吧,对比后感觉也就就是语法糖不一样而已。