react-spring icon indicating copy to clipboard operation
react-spring copied to clipboard

api.set does not work, in the onResolve callback

Open Ryuurock opened this issue 3 years ago • 1 comments

🐛 Bug Report

If there is setState in the onResolve callback, then api.set does not work

To Reproduce

https://codesandbox.io/s/hardcore-tu-e5txu

Expected behavior

api.set can work normally

Link to repro (highly encouraged)

https://codesandbox.io/s/hardcore-tu-e5txu

Environment

  • react-spring v9.2.4
  • react v17.0.2

Ryuurock avatar Aug 16 '21 13:08 Ryuurock

I was looking into this and at least found a couple workarounds.

The simpler one is to just have a useEffect that depends on count and call only setCount inside onResolve:

useEffect(() => {
  api.set({
    opacity: 0
  });
}, [count, api]);

Alternatively, if you need the call to be inside onResolve, you could make an async wrapper for setState and call api.set after it resolves:

export default function App() {
  const [styles, api] = useSpring(() => ({
    opacity: 0
  }));
  const [count, setCount] = useState(0);

  // async wrapper
  const increment = async () => {
    setCount(c => c + 1);
  };

  // could also use async/await syntax here
  const handleResolve = () => {
    increment().then(() => {
      // call api.set when Promise resolves.
      api.set({
        opacity: 0
      });
    });
  };

  return (
    <>
      <button
        onClick={() => {
          api.start({
            opacity: 1,
            onResolve: handleResolve
          });
        }}
      >
        fade in with setState {count}
      </button>
      <animated.div
        style={{ width: 100, height: 100, background: "red", ...styles }}
      />
    </>
  );
}

kindoflew avatar May 05 '22 14:05 kindoflew