简体   繁体   中英

useEffect not getting dependency value updated

I have a component that I want to edit some style dynamically. When I enter the component I want it to smoothly grow and when I leave I want it to smoothly shorten.

This is my code:

  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);
  }, []);

The variable targetScale is supposed to be updated when the mouse hovers in the element and when the mouse leaves the element.

If I print the value inside the event listeners, the value is correct. However inside the animate function, it has the initial value. Can someone point me to what I'm missing?

Is there any reason you can't use CSS transformations instead of doing the animation yourself?

Example:

 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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM