useRef未填充arrayLength

问题描述

我在TypeScript中有以下代码,我试图在其中使用useRef并分配arrayLength

const listRef = useRef(Array.from({ length: message.length },a => React.createRef()));

但是它永远不会被arrayLength填充而来

ListRef 目的 当前:[]

代码有什么问题?为什么它从不获取数组值?

解决方法

根据您所告诉我们的,唯一的解释是,自{strong>首次呼叫// Simplified type type DocumentQueryType = { collection: string; }; // The two types of queries that are accepted type QueryTypes = string | DocumentQueryType; // Given the query type,infer the doc type type InferDocType<QueryType> = QueryType extends string ? string : never; const useFirestore = <QueryType extends QueryTypes>(query: QueryType,doc?: InferDocType<QueryType>) => { } // Valid Examples useFirestore('posts','test'); useFirestore({ collection: "" }); // Valid Examples (may not want these?) useFirestore('posts'); useFirestore({ collection: "" },undefined); // Invalid Examples useFirestore({ collection: "" },"test"); // Argument of type '"test"' is not assignable to parameter of type 'undefined'.(2345) useFirestore('posts',null); // Argument of type 'null' is not assignable to parameter of type 'string | undefined'.(2345) 以来的message.lengthuseRef。之后对0的后续调用(例如,在重新渲染组件时)将忽略您传入的初始值,而是将由第一次调用创建的ref返回到useRef

这是一个简单的例子,显示了这种情况:

useRef
const { useRef,useState,useEffect } = React;

function Example({message}) {
    console.log(`Component rendered,message.length = ${message.length}`);
    const listRef = useRef(Array.from({ length: message.length },a => React.createRef()));
    console.log(`Component rendered,listRef.current.length = ${listRef.current && listRef.current.length}`);
    
    return <div>x</div>;
}

function Parent() {
    const [message,setMessage] = useState<([]);
    useEffect(() => {
        setTimeout(() => {
            setMessage([1,2,3]);
        },800);
    },[]);
    
    return <Example message={message} />;
}

ReactDOM.render(<Parent/>,document.getElementById("root"));

如果目标是扩展/收缩引用数组以匹配<div id="root"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.0/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.0/umd/react-dom.production.min.js"></script>,则必须明确地做到这一点。我不会为其使用数组,我将使用message,由Map中有关引用将用于的条目的一些唯一信息作为键。这样,当在message的开头,中间插入内容或重新排列内容时,代码不会感到困惑。可能看起来像这样:

message

...然后使用它们:

const {current: messageRefs} = useRef<Map<someType,React.RefObject<HTMLElement>>(new Map());
//                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//                                                 \
//                                                  −− this part is TypeScript-
//                                                     specific; update the
//                                                     `someType` part to match
//                                                     the type of the unique
//                                                     information you're using,//                                                     and the `HTMLElement` part
//                                                     to match the type of
//                                                     element you're storing in
//                                                     the ref
for (const {id} of message) {
    if (!messageRefs.get(id)) {
        messageRefs.set(id,React.createRef());
    }
}