【问题标题】:node.current shows up as null when using useRef(), despite using within useEffect hooknode.current 在使用 useRef() 时显示为 null,尽管在 useEffect 挂钩中使用
【发布时间】:2021-03-30 02:54:13
【问题描述】:

我的目标是大型可滚动模式,如果提供给模式的项目发生变化(底部有一个“更多项目”部分应该更改模式内容),模式会自动滚动到顶部。由于我不能使用window 对象,其他来源似乎表明ref 是最好的方法。但是,我在编译时不断收到错误node.current is undefined

我在其他地方看到,这应该可以通过在 useEffect 挂钩中使用 ref 来避免,因为这将确保 ref 在运行时已被初始化,但这里不会发生这种情况。

const PortfolioModal = ({
  open,
  handleClose,
  item,
  setItem,
  ...props
}) => {
  const node = useRef();
  
  useEffect(() => {
    node.current.scrollIntoView()
  }, [item]);

  return (
    <Dialog onClose={handleClose} open={open} fullWidth={true} maxWidth='lg'>

      <div ref={node}></div>
      <Content>
        {a bunch of stuff is here}
          <PortfolioFooter
            backgroundImage={`${process.env.PUBLIC_URL}/images/backgrounds/panel5.png`}
            item={item}
            setItem={setItem}
          />
        </FlexContainer>
        </Content>
    </Dialog>
    
  )
};

编辑:附加说明——我最初用一个带有 ref 的 div 包装了整个组件并尝试使用 scrollTop 并且我没有收到错误,但也没有滚动,所以我想我会尝试使用scrollIntoView 带有一个不可见的元素。

【问题讨论】:

  • 查看 Dialog 组件内部,可能它的子组件渲染有延迟

标签: reactjs react-hooks ref


【解决方案1】:

这对我有用,基于this post

const nodeRef = useRef();
  
  useEffect(() => {
    if (nodeRef.current) {
      nodeRef.current.scrollIntoView({
        behavior: 'smooth',
          block: 'start'
      });
    }
    
  }, [item]);

  return (
    <Dialog onClose={handleClose} open={open} fullWidth={true} maxWidth='lg' scroll="body">
      <div ref={node => {
          nodeRef.current = node;
      }}>
      <Content>
         {content}
       </Content>
      </div>
    </Dialog>

【讨论】:

  • 之所以可行,是因为在初始渲染传递您的无状态功能组件时,nodeRef 尚未附加到您的div。因此,当useEffect 被触发时,nodeRef 对象的current 切片内没有引用。当nodeRef 在第一次传递中附加到您的div 时,useRef 钩子会触发重新渲染,因此也会重新触发 useEffect。但是,这一次,nodeRef.current 中有一个节点,进入了您的useEffect 中定义的 if 语句。
猜你喜欢
  • 2020-12-13
  • 2021-02-13
  • 1970-01-01
  • 1970-01-01
  • 2020-06-27
  • 2021-07-19
  • 2020-07-14
  • 1970-01-01
  • 2021-04-23
相关资源
最近更新 更多