6

我创建了一个菜单组件,并尝试使用 useState 挂钩来存储打开的子菜单。当菜单关闭时(使用道具从父级关闭),我想关闭所有子菜单,为此我使用 react-hanger 库中的 usePrevious 挂钩来确定主菜单何时从 OPEN > CLOSED 开始。这是我的代码。

import React, { useState } from 'react';
import { usePrevious } from "react-hanger"

const defaultMenusOpen = {menu1:false, menu2:false}

function Menu(props) {

    const [subMenusOpen, setSubMenusOpen] = useState(defaultMenusOpen))
    const prevIsOpen = usePrevious(props.isOpen);


    if(props.isOpen === false && prevIsOpen === true){
        setSubMenusOpen(defaultMenusOpen)
    }

    return (
        {props.isOpen && 
            ... JSX
        }
    );

}

export default Menu

问题是这会导致无限循环错误并不断重新渲染菜单。

这似乎是因为他在每次重新渲染时 if 语句 if TRUE 因为调用 setSubMenusOpen 似乎不会导致 usePrevious 再次存储新值。这就是我认为正在发生的事情。

  • props.isOpen 从 TRUE > FALSE 变化
  • prevIsOpen 和 props.isOpen 在这一点上是 TRUE 和 FALSE,所以......
  • 调用 setSubMenusOpen() 会导致重新渲染。
  • previsOpen 和 props.isOpen 现在不是 FALSE 和 FALSE,而是保持不变,所以 setSubMenusOpen 会再次被调用,无穷无尽

任何帮助将不胜感激。

4

1 回答 1

6

问题是您直接在渲染中设置状态,这导致设置状态和重新渲染的无限循环。而是使用useEffect钩子并仅在isOpen道具更改时执行它

function Menu(props) {

    const [subMenusOpen, setSubMenusOpen] = useState(defaultMenusOpen))
    const prevIsOpen = usePrevious(props.isOpen);

    useEffect(() => {
        if(props.isOpen === false && prevIsOpen === true){
            setSubMenusOpen(defaultMenusOpen)
        }
    }, [props.isOpen])


    return (
        {props.isOpen && 
            ... JSX
        }
    );

}

export default Menu
于 2018-12-12T18:24:14.807 回答