如何在 React js 的功能组件中创建 ref?
how to create ref in functional component in react js?
我正在尝试在功能组件中创建 ref。但得到的输出与 class based component
相比有所不同。
这里很简单 class based component
。在基于 class 的组件中,我得到了正确的引用
这里是基于class的组件
https://stackblitz.com/edit/react-vh86ou?file=src%2Ftabs.js
查看参考映射 (正确的参考映射)
我正在尝试对功能组件执行相同的映射但得到不同的输出,为什么?
这是我的功能组件
https://stackblitz.com/edit/react-nagea2?file=src%2FApp.js
export default function App() {
useEffect(() => {
console.log('---', tabRefs);
}, []);
const getTabProps = ({ title, key, selected, tabIndex }) => ({
selected,
children: title,
key: tabPrefix + key,
id: tabPrefix + key,
ref: e => (tabRefs[tabPrefix + key] = e),
originalKey: key
});
我得到这个输出
为什么我从 HTMLLIELEMENT 而不是 TAB
组件获取 Ref?
更新 :
我正在尝试获取 offsetWidth
仍然无法获取
https://stackblitz.com/edit/react-nagea2?file=src%2FApp.js
useEffect(() => {
console.log('---', tabRefs);
Object.keys(tabRefs).forEach(key => {
console.log(key);
if (tabRefs[key]) {
const width = tabRefs[key].tab.offsetWidth;
console.log(width);
}
});
}, []);
您不能将 ref 属性添加到功能组件,原因如前所述here。
您可以使用 forwardRef 函数结合 useImperativeHandle 钩子来模拟 class 组件 ref,但是只要 Tab 是一个函数组件,您就不能将 ref 添加到您的 Tab 组件。
例如,您可以向 Tab 组件添加一些代码,如下所示。
const Tab = React.forwardRef(({ children }, ref) => {
const liRef = useRef(null);
React.useImperativeHandle(ref, () => ({
tab: liRef.current
}));
return <li ref={liRef}>{children}</li>;
});
export default Tab;
如果你想存储所有Tab组件的所有refs并在以后调用它的一些函数,你可以在useImperativeHandle hook中添加函数。
正如@TabW 所解释的,函数组件没有引用。但是 您不需要对 Tab
组件本身的引用 。您只需转发 ref 即可获得底层 li
元素的 offsetWidth
,而无需使用 useImperativeHandle
.
将您转发的参考直接附加到 li
:
const Tab = React.forwardRef(({ children }, ref) => {
return <li ref={ref}>{children}</li>;
});
并从您访问它的地方删除 .tab
属性。
我正在尝试在功能组件中创建 ref。但得到的输出与 class based component
相比有所不同。
这里很简单 class based component
。在基于 class 的组件中,我得到了正确的引用
这里是基于class的组件 https://stackblitz.com/edit/react-vh86ou?file=src%2Ftabs.js
查看参考映射 (正确的参考映射)
我正在尝试对功能组件执行相同的映射但得到不同的输出,为什么?
这是我的功能组件 https://stackblitz.com/edit/react-nagea2?file=src%2FApp.js
export default function App() {
useEffect(() => {
console.log('---', tabRefs);
}, []);
const getTabProps = ({ title, key, selected, tabIndex }) => ({
selected,
children: title,
key: tabPrefix + key,
id: tabPrefix + key,
ref: e => (tabRefs[tabPrefix + key] = e),
originalKey: key
});
我得到这个输出
为什么我从 HTMLLIELEMENT 而不是 TAB
组件获取 Ref?
更新 :
我正在尝试获取 offsetWidth
仍然无法获取
https://stackblitz.com/edit/react-nagea2?file=src%2FApp.js
useEffect(() => {
console.log('---', tabRefs);
Object.keys(tabRefs).forEach(key => {
console.log(key);
if (tabRefs[key]) {
const width = tabRefs[key].tab.offsetWidth;
console.log(width);
}
});
}, []);
您不能将 ref 属性添加到功能组件,原因如前所述here。 您可以使用 forwardRef 函数结合 useImperativeHandle 钩子来模拟 class 组件 ref,但是只要 Tab 是一个函数组件,您就不能将 ref 添加到您的 Tab 组件。
例如,您可以向 Tab 组件添加一些代码,如下所示。
const Tab = React.forwardRef(({ children }, ref) => {
const liRef = useRef(null);
React.useImperativeHandle(ref, () => ({
tab: liRef.current
}));
return <li ref={liRef}>{children}</li>;
});
export default Tab;
如果你想存储所有Tab组件的所有refs并在以后调用它的一些函数,你可以在useImperativeHandle hook中添加函数。
正如@TabW 所解释的,函数组件没有引用。但是 您不需要对 Tab
组件本身的引用 。您只需转发 ref 即可获得底层 li
元素的 offsetWidth
,而无需使用 useImperativeHandle
.
将您转发的参考直接附加到 li
:
const Tab = React.forwardRef(({ children }, ref) => {
return <li ref={ref}>{children}</li>;
});
并从您访问它的地方删除 .tab
属性。