0

我的申请有问题。我制作了一个包装 achildren并在其周围显示“显示更多/更少”的组件。它接受 aninitialHeight和 a MaxHeight,它们是 2 个数字,我以内联样式打印。然后我比较孩子的身高和initialHeight因为如果孩子比我允许的小,就没有必要显示显示更多的东西。

我的问题是我正在尝试处理一个特定情况:在一种情况下,孩子是一个包含 API 调用并默认显示加载器的组件。当 API 调用成功时,我会收到图像并隐藏加载程序。这意味着在最初的几秒钟内,我的孩子身高大约是 80 像素(加载器),然后可能是 600 像素或更多(图像)。所以我使用了一个observer,认为这是最好的解决方案:

import {useState, useRef, useEffect, MutableRefObject} from 'react'
import {IoIosArrowUp, IoIosArrowDown} from 'react-icons/io'
import styles from './ShowMoreWrapper.module.scss'

type PropsTypes = {
  children: React.ReactNode
  initialHeight: number
  maxHeight: number
}

const ShowMoreWrapper = ({
  children,
  initialHeight,
  maxHeight,
}: PropsTypes): JSX.Element => {
  const [innerExpand, setInnerExpand] = useState(false)
  const [showActions, setShowActions] = useState(false)
  const childrenRef = useRef() as MutableRefObject<HTMLDivElement>
  const wrapperRef = useRef<HTMLDivElement>(null)

  const observer = new ResizeObserver(entries => {
    if (entries[0].target.clientHeight > initialHeight) {
      setShowActions(true)
      setInnerExpand(false)
    }
    observer.unobserve
  })

  useEffect(() => {
    observer.observe(childrenRef.current)
  }, [childrenRef])

  const toggleExpand = () => {
    setInnerExpand(!innerExpand)
    if (wrapperRef.current && wrapperRef.current.scrollTop > 0) {
      wrapperRef.current.scrollTop = 0
    }
  }

  return (
    <>
      <div
        ref={wrapperRef}
        className={styles.contentWrapper}
        data-inner-expand={innerExpand}
        style={{
          maxHeight: innerExpand ? `${maxHeight}px` : `${initialHeight}px`,
        }}
      >
        <div ref={childrenRef}>{children}</div>
      </div>
      {showActions && (
        <div
          className={styles.innerExpandActions}
          onClick={toggleExpand}
          data-inner-expand={innerExpand}
        >
          <span>Show {innerExpand ? 'less' : 'more'}</span>
          {innerExpand ? <IoIosArrowUp /> : <IoIosArrowDown />}
        </div>
      )}
    </>
  )
}

export default ShowMoreWrapper

然后我有一些 CSS 来处理 scollbar 和溢出:

.contentWrapper {
  overflow: hidden;
  transition: max-height 0.3s ease-in-out;

  &[data-inner-expand='true'] {
    overflow: auto;
  }
}

我的问题是,当我单击Show more按钮时,它尝试设置innerExpand!innerExpand切换,但立即将自身重置为 false,可能是因为observer在重新渲染时重新定义了可能?

4

0 回答 0