最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - useState hook not working with usePrevious hook - Stack Overflow

programmeradmin2浏览0评论

I've created a menu ponent and I'm trying to use the useState hook to store which sub-menus are open. When the menu is closed (from the parent using props) I want to close all sub-menus and to do this I've using the usePrevious hook from the react-hanger library to determine when the main menu is going from OPEN > CLOSED . Here is my code.

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

The problem is that this is causing an infinite loop error and continually re-rendering the Menu.

This seems to be because he if statement if TRUE on every re-render because calling setSubMenusOpen doesn't seem to cause usePrevious to store the new value again. This is what I think is happening.

  • props.isOpen changes from TRUE > FALSE
  • prevIsOpen and props.isOpen are TRUE and FALSE at this point, so...
  • setSubMenusOpen() is called which causes a re-render.
  • Instead of previsOpen and props.isOpen now being FALSE and FALSE, they remain unchanged, so setSubMenusOpen gets called again, ad finitum

Any help would be greatly appreciated.

I've created a menu ponent and I'm trying to use the useState hook to store which sub-menus are open. When the menu is closed (from the parent using props) I want to close all sub-menus and to do this I've using the usePrevious hook from the react-hanger library to determine when the main menu is going from OPEN > CLOSED . Here is my code.

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

The problem is that this is causing an infinite loop error and continually re-rendering the Menu.

This seems to be because he if statement if TRUE on every re-render because calling setSubMenusOpen doesn't seem to cause usePrevious to store the new value again. This is what I think is happening.

  • props.isOpen changes from TRUE > FALSE
  • prevIsOpen and props.isOpen are TRUE and FALSE at this point, so...
  • setSubMenusOpen() is called which causes a re-render.
  • Instead of previsOpen and props.isOpen now being FALSE and FALSE, they remain unchanged, so setSubMenusOpen gets called again, ad finitum

Any help would be greatly appreciated.

Share Improve this question asked Dec 11, 2018 at 19:01 jonhobbsjonhobbs 28k39 gold badges118 silver badges179 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 6

Problem is that you are setting state directly in render which is causing an infinite cycle of setting state and re-rendering. Instead use the useEffect hook and execute it only on isOpen prop change

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
发布评论

评论列表(0)

  1. 暂无评论