簡體   English   中英

React 沒有呈現正確的條件元素

[英]React does not render correct conditional element

我正在使用最新版本的 react with latest mobx for state。

我試圖讓錯誤(或任何消息)出現一次,然后在操作時消失。 僅使用 state 我沒有想到簡單的方法來做到這一點,所以我“發明”的內容如下:

在 mobx state 中,我會保留是否有錯誤、錯誤及其描述。 在簡單的 JS object(對更改沒有反應)中,我會保留是否顯示此錯誤。 因此,當第一次顯示錯誤時,布局呈現 - 它保存在顯示錯誤的簡單 JS object 中,如果顯示錯誤,則第二次 - 從 mobx 中刪除它(從而更新 UI)。 這是我使用響應式和非響應式 state 一次性消息的解決方法。

然而,試圖實現我遇到了以下行為:

console.log('Render MainLayout...');

if (state.hasError || state.hasSuccess) {
    console.log('Has message');
    if (NonReactiveState.messageDisplayed) {
        console.log('Message already displayed - hiding');
        state.clearMessages();
    } else {
        console.log('Displaying message...');
        NonReactiveState.messageDisplayed = true;
    }
}

if (state.hasError) {
    console.log('Displaying error...');
    dummy = <div className="dummy-element-error"></div>
    errorAlert = (
        <Alert variant="danger">
            <Alert.Heading>{state.errorTitle}</Alert.Heading>
            <p>{state.errorDescription}</p>
        </Alert>
    )
} else {
    console.log('No error to display');
    dummy = <div className="dummy-element-no-error"></div>
}

if (state.hasSuccess) {
    console.log('Displaying success...');
    successAlert = (
        <Alert variant="success">
            <Alert.Heading>{state.successTitle}</Alert.Heading>
            <p>{state.successDescription}</p>
        </Alert>
    )
}

console.log('error el', errorAlert);
console.log('success el', successAlert);
console.log(state);

在控制台中呈現錯誤后,我有以下內容:

安慰

jsx 看起來像這樣:

...
<div className="content">
    <div className="container-fluid">
        <div className="invalid-class-bla">
            {dummy}
            {errorAlert}
            {successAlert}
        </div>
        ...
    </div>
</div>
...

但是,我無法理解為什么我的 HTML 不顯示警報,而是顯示以下內容:

html

它確實有來自正確 IF 塊的控制台日志。 它確實表明 errorAlert 不為空。 但最后在 HTML 錯誤警報是空的,並且“調試”元素包含無錯誤 class。

我可能在這里遺漏了一些真正轉儲的東西,但我堅持這一點。

歸根結底——我的“天才”想法使用非反應性 state 來處理一次性消息不適用於 React。 經過大量調試后我發現,React 出於各種原因秘密地重新渲染組件,隱藏了所有 console.log 和其他輸出。

我設置了一個 static 渲染計數器,每次調用 function 時它都會遞增 1。 我在功能組件的開頭生成一次該編號,然后在 console.log 和組件 JSX 中打印該編號。

計數器看起來像這樣:

let id = 0;

const uniqueId = () => {
    return 'id-' + id++;
};

export default uniqueId;

簡單組件:

const Debug = () => {
    const id = uniqueId();
    console.log('Render id: ' + id);

    return (
        <div className="render-id">
            {id}
        </div>
    );
};

export default Debug;

結果是組件中的 console.log 總是在渲染的 JSX 的實際內容后面 1-2 次渲染。 這意味着該組件是在后台渲染的,在我看到 console.log 打印的初始渲染之后禁用了 output。

控制台計數器 jsx計數器

這實際上意味着它多次執行“一次性”邏輯,這打破了我基於真實渲染計數的非反應式 state 的整個想法。

我想我必須考慮基於反應式 state 的單次消息渲染的另一個想法,以便 React 可以在隱藏重新渲染期間在內部管理它。

編輯

好的,經過更多調試后,我發現我的問題來自 React 在開發模式下的嚴格模式。 文件明確指出:

嚴格模式不能自動為您檢測副作用,但它可以通過使它們更具確定性來幫助您發現它們。 這是通過有意雙重調用以下函數來完成的:

  • Class 組件構造函數、渲染和 shouldComponentUpdate 方法
  • Class 組件 static getDerivedStateFromProps 方法
  • Function 組件體
  • State 更新函數(setState 的第一個參數)
  • 傳遞給 useState、useMemo 或 useReducer 的函數

如果沒有嚴格模式,功能將按預期工作......

編輯 2

我最初的陳述是錯誤的,即非反應性 state 不起作用。 它正在工作,但是對它的任何更改都必須在useEffect掛鈎中發生,因此它不會在嚴格模式雙重執行期間執行。 所以我的錯誤是我試圖直接在功能組件的主體中進行更改(副作用)。 這等於 class 組件中的 render() function。 這是不正確的。

對任何事物的任何更改,無論它是否是反應性的,都必須在useEffect掛鈎中發生,否則結果是不可預測的和隨機的。 基本錯誤,但違反了基本原則。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM