React UseEffect 不适用于 firepad 和 firebase

React UseEffect is not working with the firepad and firebase

我正在尝试使用来自 firebase 的用户名并在 FirepadUserList 中创建一个用户。代码看起来像这样

import { useRef, useEffect,useState } from 'react';
import 'codemirror/lib/codemirror.css'
import CodeMirror from 'codemirror';
import firebase from "firebase/compat";
import 'firepad/dist/firepad.css'
import classes from './Document.module.scss'
import './editor.css';
import FirepadUserList from '../../components/UserList/firepad-userlist';
import '../../components/UserList/firepad-userlist.css'
import Loading from '../../components/Loading';
import {useSession} from "../../firebase/AuthProvider";

type User = firebase.User | null;
type Loading = boolean;

function Editor() {

    const {user, loading} = useSession();
    const username = user?.displayName;
    
    const editorRef = useRef<HTMLDivElement>(null);

    let userId = Math.floor((Math.random() * 10) + 1);
   
    useEffect(() => {
          
        const codeMirror = CodeMirror(editorRef.current!, { lineWrapping: true });

        window.CodeMirror = CodeMirror;

        const Firepad = require('firepad');
        const firepadRef = getExampleRef();
      
        const firepad = Firepad.fromCodeMirror(firepadRef, codeMirror,
            { richTextToolbar: true, richTextShortcuts: true, userId:userId.toString()});
        
            FirepadUserList.fromDiv(firepadRef.child('users'),
            document.getElementById('userlist'), userId.toString(),username);
         
        firepad.on('ready', function () {
            if (firepad.isHistoryEmpty()) {
                firepad.setHtml("<div>Start typing</div>");
            }
        });
        
    }, [username]);

    
    function getExampleRef() {
        let ref = firebase.database().ref();
        const hash = window.location.hash.replace(/#/g, '');
        if (hash) {
            ref = ref.child(hash);
        } else {
            ref = ref.push(); // generate unique location.
            window.location.href = window.location + '#' + ref.key; 
        }
        if (typeof console !== 'undefined') {
            console.log('Firebase data: ', ref.toString());
        }
        return ref;
    }
    return (
        <>

            <div id="userlist" className={classes.userlist}></div>
            <div className={classes.editor} ref={editorRef}></div>


        </>
    );
}
export default Editor;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

但是如果我在 useEffect 中使用 username 变量,codeMirror 编辑器和 FirepadUserList 都会渲染两次,并且在线显示另一个用户,而它应该只有一个

但是如果使用字符串对用户名进行硬编码,如 username = "Fahim Khan",则一切正常。请注意,我使用的是 .tsx 扩展名。

好的,我得到了答案。问题是获取用户名的延迟。所以 useEffect 是 运行 两次。如果将代码包装在 useEffect 条件内 if(username != null) 它工作正常