React Native state update during animation “resets” the animation

蓝咒 提交于 2021-02-20 02:48:41

问题


I am facing a problem that I've tried to solve in lots of different ways, but I cannot get it to work. Please see this Expo application, I've created a dumb example that demonstrates my problem: https://snack.expo.io/HJB0sE4jS

To summarize, I want to build an app with a draggable component (The blue dot in the example), but while the user drags the component I also need to update the state of the app (the counter in the example). The problem is that whenever the state updates during dragging, the component resets to it's initial position. I want to allow the user to freely drag the component while state updates happen.

I was able to "solve" the issue by putting the PanResponder in a useRef, so it won't be reinitialized in case of a state update, but as you can see in the example, I want to use the state in the PanResponder. If I put it in a useRef I cannot use the state in the PanResponder because it will contain a stale value (it will always contain the initial value of the counter which is 0).

How do you handle these kind of situations in react native? I guess it is not too uncommon that someone wants to update the state during an animation, although I cannot find any documentation or examples on this.

What am I doing wrong?

Edit: I was investigating further and I can see that the problem is that I'm mapping the (dx,dy) values from the gesture parameter to the position, but the (dx,dy) values are reset to (0,0) when the state changes. I guess (dx,dy) initialized to (0,0) when PanResponder is created. Still don't know what to do to make this work...


回答1:


A mutable ref that holds the latest counter state value, along with a ref to prevent re-initializing the PanResponder should solve the problem in the example:

const [counter] = useCounter();

// Update the counterValue ref whenever the counter state changes
const counterValue = useRef(counter);
useEffect(() => {
  counterValue.current = counter;
}, [counter]);

const position = useRef(new Animated.ValueXY());
const panResponder = useRef(PanResponder.create({
    onStartShouldSetPanResponder: () => true,
    onPanResponderMove: Animated.event(
        [null, { dx: position.current.x, dy: position.current.y }],
        { listener: () => console.log(counterValue.current) } // counterValue being a ref, will not go stale
    ),
    onPanResponderRelease: () => {
        Animated.spring(position.current, { toValue: { x: 0, y: 0 } }).start();
    }
  })
);

You can check the above suggestion here: https://snack.expo.io/rkMLgp4jB

I understand though that this is a rather simplified example, and may not work for your actual use-case. It would help if you could share some more details on the actual usage!



来源:https://stackoverflow.com/questions/58780053/react-native-state-update-during-animation-resets-the-animation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!