4

Using framer-motion, I have an issue where updating the object I pass on the custom prop to the motion.div variants doesn't trigger the expected style change.

I created the following sandbox in order to demonstrate the issue:

https://codesandbox.io/s/framer-motion-stale-custom-fibp5?file=/src/App.js

My expectation is that when I toggle the theme - the circle's on/off colors will immediately change based on the new theme. (from black/white to darkblue/yellow and vice versa).

However, the theme changes are applied only once the animation value is changed (status changes from "on" to "off" etc.) So when I toggle the theme, I'm showing a "stale" theme value until I also toggle the status (on/off).

Any help would be greatly appreciated.

itaydafna
  • 1,193
  • 8
  • 17
  • 1
    I opened the sandbox and just letting you know there was a bunch of parsing errors to close out before I was able to see the page. – stuartambient Sep 24 '20 at 21:01
  • Thanks for the feedback @stuartambient! Strange - just tried running the link on incognito mode and everything seems to parse and render fine. Are you still getting these errors? If so, can you please be more specifc? – itaydafna Sep 24 '20 at 21:51
  • 1
    Yeah, that was weird but it loaded fine now. I got here searching for a similar thing. I'm following this thread but I've tried a number of things and now thinking that variants are not going to update the state of the component. Hopefully I'm wrong. – stuartambient Sep 24 '20 at 22:02

1 Answers1

3

Yes, seems quite unexpected, maybe that's a bug.

Not sure that this will work for your use case, but what you can do right now is to use React key prop to force motion.div re render after theme change. Like that:

      <motion.div
        key={theme}
        style={styles.circle}
        variants={VARIANTS}
        animate={status}
        initial={false}
        custom={theme}
      />

Note that I also set initial={false} because otherwise animation will start at off state event if you are really at on.

Codesandbox: https://codesandbox.io/s/httpsstackoverflowcomquestions64027738-cwj9k?file=/src/App.js

Danila
  • 3,703
  • 2
  • 11
  • 32
  • In my case I have motion involved with a transition duration. I'm saying that because if I set initial to false, the component is updated but I lose the duration. It's like an on/off switch. Then, if I set initial to off on my variants the animation works but will recycle the entire animation (off to on). Neither is pretty at this point. Perhaps some tweak. Originally I was using my variants but for the property that changed I had it in both the variants object and in the component style={{}} tag. It showed promised but had a small bug I couldn't grasp. – stuartambient Sep 25 '20 at 18:16
  • 3
    Danila - using a key to re-render the motion div seems like a valid workaround and this actually what I also ended up using in my project. Still feels a bit hacky though - so I also [reported this as a bug on github](https://github.com/framer/motion/issues/784). Perhaps we'll get better insights there. Approving for now. Thanks. @stuartambient – itaydafna Sep 25 '20 at 19:04