【问题标题】:Using a property of initially undefined variable for useEffect dependency将初始未定义变量的属性用于 useEffect 依赖项
【发布时间】:2020-01-17 02:26:56
【问题描述】:

TL;DR:想要使用 listRef.current.clientWidth 来实现 useEffect 依赖。

我想创建一个列表,它会根据列表的宽度自动调整其项目的宽度。我是如此接近,但我无法检测到listRef.current.clientWidth 的变化,即<div className="dynamic-list"> 的宽度。在第一次运行时 listRef 为空,因此我不能将 listRef.current.clientWidth 用于 useEffect 依赖项。依赖项的listRef ? listRef.current.clientWidth : null 也不适用于use simple dependency warning。

const DynamicList = ({
  dataSource, renderItem, itemMaxWidth, itemHeight,
  margin, height = 500, width = 700 }) => {
  const windowWidth = useWindowDimensions().width; 
  const [itemStyle, setItemStyle] = useState({ width: itemMaxWidth, height: itemHeight });
  const [currentWidth, setCurrentWidth] = useState(null);
  const listRef = useRef();


  useEffect(() => {
    if (listRef) {
      const num = Math.floor(listRef.current.clientWidth / itemMaxWidth)
      console.log(
        num,
        listRef.current.clientWidth,
        listRef.current
      )
      setItemStyle((pre) => ({
        ...pre,
        height: itemHeight,
        margin: margin,
        width: (listRef.current.clientWidth / num) - (margin ? margin * 2 : 0),
      }))
    }

  }, [listRef, windowWidth, itemMaxWidth, margin, itemHeight, width])

  return (
    <div
      className="dynamic-list"
      ref={listRef}
      style={{
        width: width,
        height: height
      }}
    >
      {
        dataSource.map((item, index) => {
          return (
            <div style={itemStyle} key={index}>
              {renderItem(item, index)}
            </div>
          )
        })
      }
    </div>
  );
};

export default DynamicList;
  • 我们将不胜感激任何有关改进此功能的提示。

【问题讨论】:

  • 你可以使用回调参考
  • 不确定我是否明白你想要做的事情。 1、如果你想检测变化,为什么要使用useRef? useRef 不会在其内容更改时通知您。 2,我不明白listRef 是null。您在那里创建一个参考。 listRef.current 可能是 null,因为您没有提供初始值。如果这是一个问题,你可以提供一个。
  • @thisismydesign 1. 为了获得div 的宽度,我必须通过div 的ref 访问它 2. 谷歌搜索后,我猜你是对的。 useRef 返回一个对象。我不知道为什么我说listRef 是null。我可能应该写listRef.current 是null。感谢您指出这一点
  • 那么分配一个起始状态呢?例如。 useRef({})

标签: javascript node.js reactjs npm


【解决方案1】:

使用@TopW3 所说的回调引用,我能够解决问题。虽然不完全满意。 Article that also helped me solve the problem

const DynamicList = ({
  dataSource, renderItem, itemMaxWidth, itemHeight,
  margin, height = 500, width = 700 }) => {
  const windowWidth = useWindowDimensions().width; // 윈도우 크기 변화 감지용
  const [itemStyle, setItemStyle] = useState({
    width: itemMaxWidth,
    height: itemHeight,
    margin: margin
  });
  const [listWidth, setListWidth] = useState(null);

  const onListRefSet = useCallback((ref) => {
    if (ref)
      if (ref.current)
        setListWidth(ref.current.clientWidth);
  })

  useEffect(() => {
    if (listWidth) {
      const num = Math.floor(listWidth / itemMaxWidth);
      setItemStyle((pre) => ({
        ...pre,
        width: (listWidth / num) - (margin ? margin * 2 : 0),
      }))
    }
  }, [listWidth, itemMaxWidth, margin, itemHeight, windowWidth])

  return (
    <div
      className="dynamic-list"
      ref={onListRefSet}
      style={{
        width: width,
        height: height,
        minWidth: itemMaxWidth
      }}
    >
      {
        dataSource.map((item, index) => {
          return (
            <div style={itemStyle} key={index}>
              {renderItem(item, index)}
            </div>
          )
        })
      }
    </div>
  );
};

export default DynamicList;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-09
    • 2021-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-09
    • 2012-08-26
    相关资源
    最近更新 更多