Uncaught Invariant Violation: визуализировано больше хуков, чем во время предыдущего рендеринга - PullRequest
1 голос
/ 11 апреля 2019

У меня есть компонент, который выглядит следующим образом (очень упрощенная версия):

const component = (props: PropTypes) => {

    const [allResultsVisible, setAllResultsVisible] = useState(false);

    const renderResults = () => {
        return (
            <section>
                <p onClick={ setAllResultsVisible(!allResultsVisible) }>
                    More results v
                </p>
                {
                    allResultsVisible &&
                        <section className="entity-block--hidden-results">
                            ...
                        </section>
                }
            </section>
        );
    };

    return <div>{ renderResults() }</div>;
}

Когда я загружаю страницу, на которой используется этот компонент, я получаю эту ошибку: Uncaught Invariant Violation: Rendered more hooks than during the previous render. Я пытался найтиобъяснение этой ошибки, но мой поиск не дал результатов.

Когда я немного изменяю компонент:

const component = (props: PropTypes) => {

    const [allResultsVisible, setAllResultsVisible] = useState(false);

    const handleToggle = () => {
        setAllResultsVisible(!allResultsVisible);
    }

    const renderResults = () => {
        return (
            <section>
                <p onClick={ handleToggle }>
                    More results v
                </p>
                {
                    allResultsVisible &&
                        <section className="entity-block--hidden-results">
                            ...
                        </section>
                }
            </section>
        );
    };

    return <div>{ renderResults() }</div>;
}

Я больше не получаю эту ошибку.Это потому, что я включил функцию setState в jsx, которая возвращается renderResults?Было бы здорово получить объяснение, почему исправление работает.

Ответы [ 2 ]

2 голосов
/ 11 апреля 2019

Вы можете просто изменить событие onlick add () => перед setAllResultsVisible

<p onClick={() => setAllResultsVisible(!allResultsVisible) }> 
    More results v
</p>

, и оно будет отлично работать

2 голосов
/ 11 апреля 2019

Исправление работает, потому что первый пример кода (ошибочный) вызывает функцию внутри onClick, а второй (рабочий) передает функцию в onClick.Разница заключается в тех важных скобках, которые в JavaScript означают «вызвать этот код».

Подумайте об этом так: в первом примере кода каждый раз при отображении component вызывается renderResults,Каждый раз, когда это происходит, вызывается setAllResultsVisible(!allResultsVisible), а не ожидание щелчка.Поскольку React выполняет рендеринг по собственному расписанию, неизвестно, сколько раз это произойдет.

Из документов React:

С помощью JSX вы передаете функцию в качестве обработчика событий.вместо строки.

Реакция обработки событий Документы

Примечание: я не смог получить это точное сообщение об ошибке при запуске первого примера кодав песочнице.Моя ошибка относится к бесконечному циклу.Может быть, более поздняя версия React выдает описанную ошибку?

...