我正在使用材料ui,并且当我想在我的reactjs应用程序中使用下面的代码(组件)而不使用下面的代码时,我的应用程序运行正常,但是当我使用下面的代码时,我得到错误:无效的挂接调用。挂钩只能在功能组件的主体内部调用。。我正在为Reactjs使用Typescript。我想使用react material-ui组件
我要使用此代码(组件)
const [checked, setChecked] = React.useState(true);
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setChecked(event.target.checked);
};
<div>
<Checkbox
checked={checked}
onChange={handleChange}
inputProps={{ 'aria-label': 'primary checkbox' }}
/>
</div>
我要在这里使用
import React, { Component } from 'react'
import ApiService from "../../service/ApiService";
import Table from '@material-ui/core/Table';
import TableBody from '@material-ui/core/TableBody';
import TableCell from '@material-ui/core/TableCell';
import TableHead from '@material-ui/core/TableHead';
import TableRow from '@material-ui/core/TableRow';
import Button from '@material-ui/core/Button';
import CreateIcon from '@material-ui/icons/Create';
import DeleteIcon from '@material-ui/icons/Delete';
import Typography from '@material-ui/core/Typography';
import { Grid } from '@material-ui/core';
import Checkbox from '@material-ui/core/Checkbox';
import FormGroup from '@material-ui/core/FormGroup';
import FormControlLabel from '@material-ui/core/FormControlLabel';
import FormControl from '@material-ui/core/FormControl';
import FormLabel from '@material-ui/core/FormLabel';
class CategoryListUserComponent extends Component<any,any>{
constructor(props: any){
super(props)
this.state = {
users: [],
message: null,
checked: true
}
this.deleteUser = this.deleteUser.bind(this);
this.editUser = this.editUser.bind(this);
this.addUser = this.addUser.bind(this);
this.reloadUserList = this.reloadUserList.bind(this);
}
componentDidMount() {
this.reloadUserList();
}
reloadUserList() {
ApiService.fetchUsers()
.then((res) => {
this.setState({users: res.data})
});
}
deleteUser(userId: any) {
ApiService.deleteUser(userId)
.then(res => {
this.setState({message : 'User deleted successfully.'});
this.setState({users: this.state.users.filter((user: { id: any; }) => user.id !== userId)});
})
}
editUser(id: any) {
window.localStorage.setItem("userId", id);
this.props.history.push('/edit-user');
}
addUser() {
window.localStorage.removeItem("userId");
this.props.history.push('/add-user');
}
render() {
return (
<Grid>
<Typography variant="h4" align="left" style={style}>Category List</Typography>
<Button variant="contained" color="primary" onClick={() => this.addUser()}>
Add Category
</Button>
<Grid container className="listContainer">
<Table>
<TableHead>
<TableRow>
<TableCell>Id</TableCell>
<TableCell>Initiator</TableCell>
<TableCell align="left">Category</TableCell>
<TableCell align="left">Date</TableCell>
<TableCell align="left">Time</TableCell>
<TableCell align="left">Status</TableCell>
<TableCell align="left"></TableCell>
<TableCell align="left"></TableCell>
</TableRow>
</TableHead>
<TableBody>
{this.state.users && this.state.users.map((row: { id: {} | null | undefined; name: React.ReactNode; email: React.ReactNode; username: React.ReactNode; age: React.ReactNode; salary: React.ReactNode; }) => (
<TableRow>
<TableCell scope="row">
{row.id}
</TableCell>
<TableCell align="left">{row.name}</TableCell>
<TableCell align="left">{row.username}</TableCell>
<TableCell align="left">13-10-2020</TableCell>
<TableCell align="left">10:00 AM</TableCell>
<TableCell align="left"><FormControl component="fieldset">
<FormGroup aria-label="position" row>
<FormControlLabel
value="top"
control={<Checkbox color="primary" checked />}
label=""
labelPlacement="start"
/>
</FormGroup>
<FormGroup>
<Checkbox
onChange={(event) => {
this.setState({
checked: event.target.checked,
)}
}}
inputProps={{ 'aria-label': 'primary checkbox' }}
/>
</FormGroup>
</FormControl>
</TableCell>
<TableCell align="left" onClick={() => this.editUser(row.id)}><CreateIcon /></TableCell>
<TableCell align="left" onClick={() => this.deleteUser(row.id)}><DeleteIcon /></TableCell>
</TableRow>
))}
</TableBody>
</Table>
</Grid>
</Grid>
);
}
}
const style ={
display: 'flex',
justifyContent: 'center'
}
export default CategoryListUserComponent;
答案 0 :(得分:1)
错误是不言自明的,因为它表示只能在函数组件的主体内部调用挂钩。
CategoryListUserComponent
当前是基于类的组件React.useState
是一个钩子,只能在功能组件中使用。
有三种方法可以解决此问题:
CategoryListUserComponent
组件转换为
功能组件(推荐)。CategoryListUserComponent
,将其作为组件包含在
父组件。如@wentjun所述 您可以将以上代码转换为包含在基于类的组件中
而不是使用钩子在构造函数中定义检查状态,即
this.state = {
users: [],
message: null,
checked: true, // or false
}
并将您的JSX转换为:
<Checkbox
checked={checked}
onChange={(event) => {
this.setState({
checked: event.target.checked,
)}
}}
inputProps={{ 'aria-label': 'primary checkbox' }}
/>
答案 1 :(得分:0)
正如官方documentation中对React Hooks所述,钩子(例如useState
)只能在功能组件中使用。
CategoryListUserComponent
是一个类组件。
如果您希望使用useState挂钩,则应CategoryListUserComponent
进入功能组件。
或者,您可以简单地将checked
状态添加到CategoryListUserComponent
,使其成为组件状态的一部分。
this.state = {
users: [],
message: null,
checked: true, // or false
}
然后,只需单击this.setState()
组件,即可使用Checkbox
更新状态。
<Checkbox
checked={checked}
onChange={(event) => {
this.setState({
checked: event.target.checked,
)}
}}
inputProps={{ 'aria-label': 'primary checkbox' }}
/>
此外,我注意到您已经将道具和状态都定义为any
。不建议您这样做,因为您将无法从TypeScript的类型检查功能中受益。
例如,这就是定义界面的方式。
interface ListState {
users: Something[],
message: string | null,
checked: boolean,
}