suchen

Heim  >  Fragen und Antworten  >  Hauptteil

Nicht erfasste invariante Verletzung: Mit mehr Hooks gerendert als beim vorherigen Rendern

Ich habe eine Komponente, die so aussieht (sehr vereinfachte Version):

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>;
}

Wenn ich eine Seite lade, die diese Komponente verwendet, erhalte ich diese Fehlermeldung: Uncaught Invariant Violation: Rendered more hooks than during the previous render. Ich habe versucht, eine Erklärung für diesen Fehler zu finden, aber meine Suche hat keine Ergebnisse zurückgegeben.

Wenn ich die Komponente leicht verändere:

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>;
}

Ich bekomme diesen Fehler nicht mehr. Liegt es daran, dass ich in der renderResults 返回的 jsx 中包含了 setState-Funktion bin? Es wäre toll, wenn es eine Erklärung gäbe, warum dieser Fix funktioniert.

P粉477369269P粉477369269277 Tage vor603

Antworte allen(2)Ich werde antworten

  • P粉729198207

    P粉7291982072024-03-26 10:59:40

    我也遇到了同样的问题。我正在做的事情是这样的:

    const Table = (listings) => {
    
        const {isLoading} = useSelector(state => state.tableReducer);
    
        if(isLoading){
            return <h1>Loading...</h1>
        }
    
        useEffect(() => {
           console.log("Run something")
        }, [])
    
        return (<table>{listings}</table>)
    }

    我认为发生的情况是在第一次渲染时,组件提前返回并且 useEffect 没有运行。当 isLoading 状态更改时,useEffect 运行,我收到错误 - 钩子渲染的次数比之前的渲染次数多。

    一个简单的更改就解决了这个问题:

    const Table = (listings) => {
        
        const {isLoading} = useSelector(state => state.tableReducer);
            
        useEffect(() => {
            console.log("Run something")
        }, [])
        
        if(isLoading){
            return <h1>Loading...</h1>
        }
        return (<table>{listings}</table>)
    }

    Antwort
    0
  • P粉448346289

    P粉4483462892024-03-26 10:39:49

    该修复之所以有效,是因为第一个代码示例(出错的代码)调用了 onClick 内的函数,而第二个代码示例(有效的代码示例)则将函数传递给了 onClick。区别在于那些非常重要的括号,在 JavaScript 中意味着“调用此代码”。

    这样想:在第一个代码示例中,每次渲染 component 时,都会调用 renderResults。每次发生这种情况时,都会调用 setAllResultsVisible(!allResultsVisible),而不是等待单击。由于 React 按照自己的时间表执行渲染,因此无法确定会发生多少次。

    来自 React 文档:

    React 处理事件文档

    注意:在沙箱中运行第一个代码示例时,我无法获得确切的错误消息。我的错误涉及无限循环。也许较新版本的 React 会产生所描述的错误?

    Antwort
    0
  • StornierenAntwort