useEffect не получает обновленное значение зависимости - PullRequest
1 голос
/ 04 февраля 2020

У меня есть компонент, который я хочу динамически редактировать. Когда я вхожу в компонент, я хочу, чтобы он плавно увеличивался, а когда я ухожу, я хочу, чтобы он плавно сокращался.

Это мой код:

  const easing = 0.1;
  const outScale = 0.6;
  const inScale = 1;
  let targetScale = outScale;
  let elementScale = targetScale;
  let innerScale = 1 / elementScale;

  const [parentTransformStyle, setParentTransformStyle] = useState(
    `scale(${elementScale})`
  );
  const [innerTransformStyle, setInnerTransformStyle] = useState(
    `scale(${innerScale})`
  );
  const requestRef = useRef();

  const onPointOverEvent = () => {
    targetScale = inScale;
    console.log("over", inScale, targetScale);
  };

  const onPointerOutEvent = () => {
    targetScale = outScale;
    console.log("out", outScale, targetScale);
  };

  const animate = () => {
    console.log("animate", targetScale);

    elementScale += (targetScale - elementScale) * easing;
    innerScale = 1 / elementScale;

    setParentTransformStyle(`scale(${elementScale})`);
    setInnerTransformStyle(`scale(${innerScale})`);

    requestAnimationFrame(animate);
  };

  useEffect(() => {
    requestRef.current = requestAnimationFrame(animate);
    return () => cancelAnimationFrame(requestRef.current);
  }, []);

Предполагается, что переменная targetScale обновляться, когда мышь находится в элементе и когда мышь покидает элемент.

Если я распечатаю значение в обработчиках событий, значение будет правильным. Однако внутри функции animate она имеет начальное значение. Может кто-нибудь указать мне на то, что мне не хватает?

1 Ответ

2 голосов
/ 04 февраля 2020

Есть ли причина, по которой вы не можете использовать CSS преобразования вместо анимации самостоятельно?

Пример:

function MyComponent() {
  const [innerTransformStyle, setInnerTransformStyle] = React.useState(
    `scale(${0.6})`
  );

  const onPointOverEvent = () => {
    setInnerTransformStyle(`scale(${1})`);
  };

  const onPointerOutEvent = () => {
    setInnerTransformStyle(`scale(${0.6})`);
  };
  
  return (
    <div className="parent">
      <div className="element" style={{transform: innerTransformStyle}} onPointerOut={onPointerOutEvent} onPointerOver={onPointOverEvent}></div>
    </div>
  );
}

ReactDOM.render(<MyComponent/>, document.getElementById("app"));
.parent {
  width: 100px;
  height: 100px;
  background-color: #f00;
}

.element {
  width: 100px;
  height: 100px;
  background-color: #0f0;
  transition: transform 1s;
}
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>

<div id="app"></div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...