无法读取为空的属性“offsetWidth”?
2021-07-03
3376
我正在尝试将一个小的 jquery 组件转换为 react。但我遇到了这个问题
无法读取 null 的属性“offsetWidth”
这是 jquery 简单组件 http://jsfiddle.net/abhitalks/860LzgLL/
它显示“菜单或选项卡列表”的组件是什么。如果窗口屏幕缩小,它会隐藏菜单并移动到下拉菜单,如下所示
我试图实现的是 react。
我的方法是
-
首先,我要计算
li
的宽度或所有 li 宽度的总和。 - 还要获取容器的宽度。
-
如果 li 宽度的总和大于,我
设置阈值
。使用阈值进行渲染
但是当我调整组件大小时,出现以下错误
**无法读取 null 的属性“offsetWidth”**
这是我的代码 https://stackblitz.com/edit/react-wmtunp?file=src%2FApp.js
import React, { useState, useRef, createRef, useEffect } from 'react';
import './style.css';
const data = [
'Option One',
'Option_hellodummyhhhsdshshshd',
'Option Three',
'Option Four',
'Option Five'
];
export default function App() {
const [state, setState] = useState(data);
const [threshold, setThreshold] = useState(-1);
const liRefs = useRef([]);
const ulRef = useRef(null);
liRefs.current = state.map((_, i) => liRefs.current[i] ?? createRef());
const adjustItems = function() {
var skipLoop = false,
w2W = ulRef.current.offsetWidth,
index = -1,
totalW = 0;
liRefs.current.map(function(li, key) {
if (skipLoop) {
return;
}
totalW += li.current.offsetWidth;
if (totalW > w2W) {
skipLoop = true;
index = key;
}
setThreshold(index);
});
};
useEffect(() => {
adjustItems();
window.addEventListener('resize', adjustItems);
return () => window.removeEventListener('resize', adjustItems);
}, []);
return (
<div>
<ul id="menu" ref={ulRef}>
{state.map((i, index) =>
threshold == -1 ? (
<li ref={liRefs.current[index]} key={index}>
{i}
</li>
) : threshold !== -1 && threshold >= index ? (
<li ref={liRefs.current[index]} key={index}>
{i}
</li>
) : (
<></>
)
)}
</ul>
<ol>
<li>
Collected
<ul id="submenu">
{state.map((i, index) =>
threshold !== -1 && threshold <= index ? (
<li ref={liRefs.current[index]} key={index}>
{i}
</li>
) : (
<></>
)
)}
</ul>
</li>
</ol>
</div>
);
}
当我调整窗口大小时,我的功能中断。 我是 React js 的新手。我的方法有问题吗?有什么建议吗?
1个回答
只需尝试使用 ? 此运算符,因为当您调整大小时,它可能会根据条件获取 null 或未定义,但通过设置此条件,它将帮助您进行“and”检查,以确定属性值是否存在。
import React, { useState, useRef, createRef, useEffect } from 'react';
import './style.css';
const data = [
'Option One',
'Option_hellodummyhhhsdshshshd',
'Option Three',
'Option Four',
'Option Five'
];
export default function App() {
const [state, setState] = useState(data);
const [threshold, setThreshold] = useState(-1);
const liRefs = useRef([]);
const ulRef = useRef(null);
liRefs.current = state.map((_, i) => liRefs.current[i] ?? createRef());
const adjustItems = function() {
let skipLoop = false,
w2W = ulRef.current.offsetWidth,
totalW = 0;
liRefs.current.map((li, key) => {
if (skipLoop) {
return;
}
totalW += li?.current?.offsetWidth;
if (totalW > w2W) {
skipLoop = true;
setThreshold(key);
} else {
setThreshold(liRefs.current.length);
}
});
};
useEffect(() => {
adjustItems();
window.addEventListener('resize', adjustItems);
return () => window.removeEventListener('resize', adjustItems);
}, []);
return (
<div>
<ul id="menu" ref={ulRef}>
{state.map((i, index) =>
threshold == -1 ? (
<li ref={liRefs.current[index]} key={index}>
{i}
</li>
) : threshold !== -1 && threshold > index ? (
<li ref={liRefs.current[index]} key={index}>
{i}
</li>
) : (
<></>
)
)}
</ul>
<ol>
<li>
Collected
<ul id="submenu">
{state.map((i, index) =>
threshold !== -1 && threshold <= index ? (
<li ref={liRefs.current[index]} key={index}>
{i}
</li>
) : (
<></>
)
)}
</ul>
</li>
</ol>
</div>
);
}
您可以参考它 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining
Divya
2021-07-03