我想创建一个列表,该列表会根据列表的宽度自动调整其项目的宽度。我是如此接近,但是我无法检测到listRef.current.clientWidth宽度的变化<div className="dynamic-list">。第一次运行时,listRef为null,所以useEffect依赖项没有listRef.current.clientWidth。依赖项的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;
  • 任何使它变得更好的技巧将不胜感激。
  • 最佳答案

    使用@ TopW3这样的回调ref,我能够解决问题。虽然不完全满意。
    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;
    

    09-30 19:19