Реактивное обновление собственного состояния во время анимации «сбрасывает» анимацию - PullRequest
0 голосов
/ 09 ноября 2019

Я столкнулся с проблемой, которую пытался решить разными способами, но не могу заставить ее работать. Пожалуйста, посмотрите это приложение Expo, я создал глупый пример, который демонстрирует мою проблему: https://snack.expo.io/HJB0sE4jS

Подводя итог, я хочу создать приложение с перетаскиваемым компонентом (синяя точка в примере), нов то время как пользователь перетаскивает компонент, мне также нужно обновить состояние приложения (счетчик в примере). Проблема заключается в том, что всякий раз, когда состояние обновляется во время перетаскивания, компонент сбрасывается в исходное положение. Я хочу, чтобы пользователь мог свободно перетаскивать компонент во время обновления состояния.

Я смог «решить» проблему, поместив PanResponder в useRef, поэтому он не будет повторно инициализирован в случаеобновление состояния, но, как вы можете видеть в примере, я хочу использовать состояние в PanResponder. Если я помещу его в useRef, я не смогу использовать состояние в PanResponder, потому что оно будет содержать устаревшее значение (оно всегда будет содержать начальное значение счетчика, равное 0).

Как вы справляетесь с этим видомситуаций в родной реакции? Я предполагаю, что это не является чем-то необычным, что кто-то хочет обновить состояние во время анимации, хотя я не могу найти какую-либо документацию или примеры по этому поводу.

Что я делаю не так?

Редактировать: Iпродолжал исследовать дальше, и я вижу, что проблема в том, что я сопоставляю значения (dx, dy) из параметра жеста с позицией, но значения (dx, dy) сбрасываются в (0,0), когда состояниеменяется. Я думаю, (dx, dy) инициализируется в (0,0) при создании PanResponder. До сих пор не знаю, что делать, чтобы сделать эту работу ...

1 Ответ

0 голосов
/ 10 ноября 2019

Изменяемая ссылка, содержащая последнее значение состояния счетчика, а также ссылка для предотвращения повторной инициализации PanResponder должна решить проблему в следующем примере:

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();
    }
  })
);

Вы можете проверить приведенное выше предложение здесь:https://snack.expo.io/rkMLgp4jB

Я понимаю, что это довольно упрощенный пример, который может не сработать для вашего фактического варианта использования. Было бы полезно, если бы вы могли поделиться некоторыми подробностями о фактическом использовании!

...