开发者问题收集

无法读取为空的属性“offsetWidth”?

2021-07-03
3376

我正在尝试将一个小的 jquery 组件转换为 react。但我遇到了这个问题 无法读取 null 的属性“offsetWidth”

这是 jquery 简单组件 http://jsfiddle.net/abhitalks/860LzgLL/

它显示“菜单或选项卡列表”的组件是什么。如果窗口屏幕缩小,它会隐藏菜单并移动到下拉菜单,如下所示 在此处输入图像描述

我试图实现的是 react。

我的方法是

  1. 首先,我要计算 li 的宽度或所有 li 宽度的总和。
  2. 还要获取容器的宽度。
  3. 如果 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