Хук useState не работает с хуком usePrevious - PullRequest
0 голосов
/ 11 декабря 2018

Я создал компонент меню и пытаюсь использовать хук useState для хранения открытых подменю.Когда меню закрыто (от родителя с помощью реквизита), я хочу закрыть все подменю, и для этого я использую хук usePrevious из библиотекиact-hanger, чтобы определить, когда главное меню переходит из 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 TRUE onкаждый повторный рендеринг, потому что вызов setSubMenusOpen, по-видимому, не приводит к тому, что usePrevious снова сохраняет новое значение.Это то, что, я думаю, происходит.

  • props.isOpen меняет значение TRUE> FALSE
  • prevIsOpen и props.isOpen на данный момент TRUE и FALSE, поэтому ...
  • вызывается setSubMenusOpen (), что вызывает повторную визуализацию.
  • Вместо previsOpen и props.isOpen, теперь являющихся FALSE и FALSE, они остаются неизменными, поэтому метод setSubMenusOpen вызывается снова, ad finitum

Любая помощь будет принята с благодарностью.

1 Ответ

0 голосов
/ 12 декабря 2018

Проблема в том, что вы устанавливаете состояние непосредственно при рендеринге, что вызывает бесконечный цикл установки состояния и повторного рендеринга.Вместо этого используйте хук 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
...