使用useMeasure挂钩和React Spring

时间:2019-04-29 12:42:50

标签: react-hooks react-spring

我正在尝试将React Spring与hooks API配合使用,以在正常渲染宽度和0px之间插入跨度的宽度。

我一直以以下示例为基础:https://codesandbox.io/embed/lp80n9z7v9

useMeasure挂钩:

import React, { useState, useRef, useEffect } from 'react';
import ResizeObserver from 'resize-observer-polyfill';

export default function useMeasure() {
  const ref = useRef();
  const [bounds, set] = useState({ left: 0, top: 0, width: 0, height: 0 });
  const [ro] = useState(
    () => new ResizeObserver(([entry]) => set(entry.contentRect))
  );
  useEffect(() => {
    if (ref.current) ro.observe(ref.current);
    return () => ro.disconnect();
  }, []);
  return [{ ref }, bounds];
}

这是我的组件代码:

export default function MyComponent({
  hasChildren,
  icon,
  isOpen,
  title,
  url,
  visible
}) {
  const tabIndex = visible ? undefined : -1;
  const titleAttr = (isOpen && title) || undefined;
  const wrapperRef = useRef();
  const titleRef = useRef();
  const [bind, { width: viewWidth }] = useMeasure();

  const wrapperProps = useSpring({
    config: animationConfig,
    ref: wrapperRef,
    opacity: isOpen ? 0 : 1,
  });

  const titleProps = useSpring({
    ref: titleRef,
    width: isOpen ? 0 : viewWidth
  });

  // Chain animation order
  useChain([wrapperRef, titleRef]);

  return (
    <OuterComponent
      className="side-nav__nav-link"
      to={url}
      tabIndex={tabIndex}
      title={titleAttr}
    >
      {icon && (
        <img
          className="side-nav__nav-link__icon"
          src={`${process.env.PUBLIC_URL}${icon}`}
          alt=""
        />
      )}

      <animated.div
        className="wrapper"
        style={{
          opacity: wrapperProps.opacity
        }}
      >
        <animated.span
          style={{
            width: titleProps.width
         }}
        >
          <span className="title" {...bind}>
            {title}
          </span>
        </animated.span>
        {hasChildren && hasChildren.length > 0 && (
          <span className="icon" />
        )}
      </animated.div>
    </OuterComponent>
  );
}

我遇到的问题是,在第一个渲染viewWidth上将其计算为0,然后将其设置为内联样式,因此将来的任何度量也将为0。

如果您删除将样式传递到内部animated.span的行,则可以正确计算宽度(将viewWidth登录到控制台)。

在我在本文顶部发布的示例URL中,这似乎不是问题。我不确定如何解决这个问题。

0 个答案:

没有答案