我正在尝试编写用于滚动到功能的 Reactjs 代码。我希望为“标签”数组的元素生成不同部分的引用 ID。
import { useRef } from 'react';
const useDivRefs = (labels) => {
const divRefs = {};
labels.forEach((label, i) => {
const targetId = label.replace(/\s+/g, '');
const ref = useRef(null);
divRefs[targetId] = ref;
});
return divRefs;
};
const MyComponent = () => {
const labels = [
'div 1',
'div 2',
'div 3',
];
const divRefs = useDivRefs(labels);
console.log('divRefs = ', divRefs);
return divRefs;
};
它可以工作,但是“const ref = useRef(null);”行显示以下错误
“React Hook“useRef”不能在回调内部调用。React Hooks 必须在 React 函数组件或自定义 React Hook 函数react-hooks/rules-of-hooks 中调用”
我怎样才能摆脱这个错误? 任何帮助将不胜感激。
React hooks 很特别。您只能将 React hooks 调用为 React 函数组件或自定义 hooks 中的顶级函数。
还可以查看 - https://legacy.reactjs.org/warnings/invalid-hook-call-warning.html
为了您的目的,您可以使用保存数组的
useRef
。
const divRefs = useRef([]);
...
{items.map((item, i) => (
<div
key={i}
ref={el => itemsRef.current[i] = el} >
...
</div>
))}
由于 React 处理钩子的方式,每个组件实例它们需要具有相同的确定性顺序。这就是为什么它们需要位于组件的顶层,或者位于其他钩子内。
因此,您无法安全地管理引用数组或引用对象(如果可能的话,还有很多其他复杂的情况如何工作)。
在类似的情况下,可以使用对数组的引用,或对对象的引用。
但是,你的案子似乎有点复杂:
const useDivRefs = (labels) => {
const divRefs = useRef({});
useEffect(() => {
const tmp = {};
labels.forEach((label, i) => {
const targetId = label.replace(/\s+/g, '');
tmp[targetId] = null;
});
divRefs.current = tmp;
}, [labels]);
return divRefs;
};
然后您可以像以前一样使用 ref 对象,只需添加额外的
.current
。
React hooks,包括“useRef”,不能在功能组件顶层之外的任何块内调用。它们必须始终在功能组件主体内直接调用。
可以像这样以编程方式创建引用:
const [refMapping, setRefMapping] = useState< { [key: string]: any }>({});
useEffect(() => {
// Create a new array of refs whenever items change
const refMapping = myList.reduce((prevVal, curVal) => {
const newObject: any = { ...prevVal }
newObject[curVal.key] = React.createRef()
return newObject
}, {})
setRefMapping(refMapping);
}, [myList]);