【问题标题】:Accidental early return statement意外提前退货声明
【发布时间】:2021-02-07 18:36:09
【问题描述】:

我试图使用 Material UI 在 React 中创建一个响应式导航栏,但是当窗口大小减小到 900 像素以下时,此代码会崩溃,并给出错误 Error: Rendered less hooks than expected.这可能是由于意外提前返回语句造成的。 错误在 useEffect 挂钩中。但我就是不明白为什么这会给我一个错误。我猜这是因为违反了钩子规则。但是我已经尝试了所有方法,但仍然无法修复它。

import React,{useEffect,useState} from 'react'
import {AppBar ,Toolbar, Container ,makeStyles,Button, IconButton ,Drawer} from '@material-ui/core'
import MenuIcon from '@material-ui/icons/Menu'

const usestyles = makeStyles({
  root:{
    display:'flex',
    justifyContent:'space-between' ,
    maxWidth:'700px'
  },
  menubtn:{
    fontFamily: "Work Sans, sans-serif",
    fontWeight: 500,
    paddingRight:'79px',
    color: "white",
    textAlign: "left",
  },
  menuicon:{
    edge: "start",color: "inherit",paddingLeft:'0'
  }
})

const menudata = [
  {
    label: "home",
    href: "/",
  },
  {
    label: "About",
    href: "/about",
  },
  {
    label: "Skill",
    href: "/skills",
  },
  {
    label: "Projects",
    href: "/projects",
  },
  {
    label: "Contact",
    href: "/contact",
  },
];


function Navbar() {
  const [state, setState] = useState({mobileview:false,draweropen:false});
  const {mobileview,draweropen} = state;
  const {menuicon,root} =usestyles();


  function getmenubuttons(){
    const {menubtn} = usestyles();
    return menudata.map(({label,href})=>{
      return <Button className={menubtn}>{label}</Button>
    })
  }


  function displaydesktop(){

    return <Toolbar >
      <Container maxWidth={false} className={root}>
        {getmenubuttons()}
      </Container>
    </Toolbar>
  }

  function displaymobile(){

    return <Toolbar>
      <IconButton className={menuicon} >
        <MenuIcon />
      </IconButton>

    </Toolbar>
  }

  useEffect(() => {
    const setResponsiveness = () => {
      return window.innerWidth < 900
        ? setState((state)=>({ ...state, mobileview: true }))
        : setState((state)=>({ ...state, mobileview: false }));
    };

    setResponsiveness();

    window.addEventListener("resize", () => setResponsiveness());
  }, []);

  return (
    <div>
      <AppBar> {mobileview? displaymobile() :displaydesktop() } </AppBar>
    </div>
  )
}

export default Navbar;

【问题讨论】:

    标签: reactjs react-hooks use-effect


    【解决方案1】:

    usestyles 是一个钩子,您在桌面设备上调用它两次,但在移动设备上只调用一次,因为移动设备不使用菜单按钮。要解决此问题,您可以为菜单创建一个单独的组件并将其添加到桌面视图。该组件将在其自身内部调用usestyles,因此父组件在每个渲染中将具有相同数量的钩子。

    所以你变了

    function getmenubuttons(){
      const {menubtn} = usestyles();
      return menudata.map(({label,href})=>{
        return <Button className={menubtn}>{label}</Button>
      })
    } 
    

    进入

    function MenuButtons({menudata}){
      const {menubtn} = usestyles();
    
        return (<>
         {menudata.map(({label,href})=>  <Button className={menubtn}>{label}</Button>)}
         </>)
    } 
    

    【讨论】:

    • 嘿你的修复工作但我仍然对错误的原因有点困惑,就像错误是因为 useStyles() 钩子在条件内被调用但是通过制作菜单按钮(钩子的父) 一个我们也可以在条件内使用钩子的组件?我是钩子的初学者,所以如果你能多解释一下这将非常有帮助
    • 没错,钩子和它们的组件相关联,你需要每个组件有相同数量的钩子,但它的子组件和它们的钩子不算数。
    【解决方案2】:

    您在useEffect 中调用的setState 没有任何依赖关系或条件,将导致重新渲染的无限循环。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-04
      • 2013-07-11
      • 2011-08-10
      • 2022-11-18
      • 2021-11-15
      • 2017-06-06
      • 2016-06-23
      • 2012-01-02
      相关资源
      最近更新 更多