问题描述
我在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.length
是useRef
。之后对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());
}
}