【问题标题】:React Hook "useState" cannot be called in a class component. React Hooks must be called in a React function component or a custom React Hook function不能在类组件中调用 React Hook “useState”。必须在 React 函数组件或自定义 React Hook 函数中调用 React Hooks
【发布时间】:2021-06-24 18:53:08
【问题描述】:

我是 React 前端开发的新手。我正在尝试向我的 Material-UI NavBar 添加一个临时抽屉。我在代码中添加了一个抽屉:

class Navbar extends Component {
    render() {
        const { authenticated } = this.props;
        const [open, setOpen] = useState(false);
        const handleDrawer = () =>{
           setOpen(true)
        }
        return (
            <AppBar position="fixed">
                <Toolbar className="nav-container">
                    {authenticated ? (
                        <Fragment>
                            <IconButton edge="start" onClick={handleDrawer} >
                                <Menu/>
                            </IconButton>
                            <Drawer
                                anchor='left'
                                open={open}
                                onClose={()=> setOpen(false)}
                                >
                                    <h3> Drawer</h3>
                            </Drawer>
                            <NewPost/>
                            <Link to="/">
                                <MyButton tip="Home">
                                    <HomeIcon color = "disabled"/>
                                </MyButton>
                            </Link>
                            <Link to="/chats">
                                <MyButton tip="Chats">
                                    <ChatIcon color = "disabled"/>
                                </MyButton>
                            </Link>
                            <Notifications />
                        </Fragment>
                        

                    ):(
                        <Fragment>
                            <Button color="inherit" component={Link} to="/login">Login</Button>
                            <Button color="inherit" component={Link} to="/signup">Singup</Button>
                            <Button color="inherit" component={Link} to="/">Home</Button>
                            {/* <Button color="inherit" component={Link} to="/user">Profile</Button>*/}
                        </Fragment>
                    )}
                </Toolbar>
            </AppBar>

            
        )
    }
}

Navbar.propTypes = {
    authenticated:  PropTypes.bool.isRequired
}

const mapStateToProps = state =>({
    authenticated: state.user.authenticated
})

export default connect(mapStateToProps)(Navbar)

但是出现了这个错误:

React Hook "useState" cannot be called in a class component. React Hooks must be called in a React function component or a custom React Hook function

所以,我创建了一个构造函数来处理这个(在渲染之前):

constructor(props) {
    super(props);
    this.state = {
      open: false
    };
  }

当我想改变状态时,我使用了:

this.setState({ open: true })

但是,当我触发抽屉(单击按钮)时,它并没有打开。我能做什么?

【问题讨论】:

  • 试试open={this.state.open} 而不是open={open}
  • 或者const { open } = this.state;在渲染方法的顶部,所以open={open}可以工作。

标签: javascript reactjs material-ui


【解决方案1】:

状态挂钩 (useState) 可用于功能性 React 组件,但在您的情况下,您使用的是 Class 组件。功能性 React 组件通常没有开箱即用的状态,但 useState 是一个新功能,可以让您解决这个问题

您可以将其更改为功能组件,也可以将其保留为类组件并以不同的方式使用状态 例如:

  • !this.state.open 而不是 !open
  • this.setState({open: false}) 而不是 setOpen(false)

https://reactjs.org/docs/hooks-state.html

【讨论】:

    【解决方案2】:

    将此行 const [open, setOpen] = useState(false); 更改为 this.state = { open: false };

    当设置为 true 时,只需调用 this.setState({ open: this.state.open: true })

    【讨论】:

      【解决方案3】:

      函数组件而不是类组件呢? 如您所知,推荐使用功能组件。 我认为它很容易编码,并且可以提高性能。

      const Navbar = () => {
           //useState, define functions here
           return (//the same as render method of your class component) 
      }
      

      【讨论】:

        【解决方案4】:

        您必须使用功能组件。目前你的组件是一个类组件,所以你应该有类似的东西:

        const Navbar = (props) => {
          const { authenticated } = props;
          const [open, setOpen] = useState(false);
          const handleDrawer = () =>{
            setOpen(true)
          }
            
          return (
            <AppBar position="fixed">...</AppBar>
          );
        };
        

        我还注意到您的类组件具有在渲染方法中定义的状态部分。使用类组件时,应在constructor 中定义状态,否则每次渲染都会覆盖您的状态。

        【讨论】:

          【解决方案5】:

          使用function Navbar(props) 代替class Navbar extends Component

          这是因为,有一条规则:React Hook "useState" 不能在 class component 中调用,例如class Navbar extends Component 。必须在 React function component 中调用 React Hooks,例如function Navbar(props) 或自定义 React Hook 函数

          【讨论】:

            猜你喜欢
            • 2020-10-26
            • 2021-03-20
            • 2021-11-27
            • 2019-10-21
            • 2020-03-18
            • 2019-09-14
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多