Код-ревью Middle Анимации и жесты обновлено

Код-ревью: перетаскиваемая карточка

Вопрос

Компонент перетаскиваемой карточки. Найдите проблемы производительности и логики.

export function DraggableCard() {
  const [x, setX] = useState(0);
  const pan = useRef(
    PanResponder.create({
      onMoveShouldSetPanResponder: () => true,
      onPanResponderMove: (_, g) => setX(g.dx),
      onPanResponderRelease: () => setX(0),
    }),
  ).current;
  const opacity = useRef(new Animated.Value(1)).current;
  useEffect(() => {
    Animated.timing(opacity, { toValue: 0.5, duration: 300, useNativeDriver: true }).start();
  });
  return (
    <Animated.View {...pan.panHandlers} style={{ transform: [{ translateX: x }], opacity, width: 300 }}>
      <HeavyContent />
    </Animated.View>
  );
}

Коротко

Перетаскивание делают так, чтобы React не участвовал в каждом кадре: Gesture.Pan меняет shared value, useAnimatedStyle применяет сдвиг на UI-потоке, возврат через withSpring. Жест активируется только по горизонтали (activeOffsetX).

Что должен найти ревьюер

  1. Производительностьстрока 6
    setState на каждое движение пальца: перерисовка компонента с тяжёлым содержимым 60+ раз в секунду через JS-поток. Нужен Gesture Handler + Reanimated (или Animated.event).
  2. Ошибкастрока 5
    onMoveShouldSetPanResponder: () => true перехватывает любое движение, включая вертикальную прокрутку родительского списка.
  3. Стильстрока 7
    Возврат на место без анимации: карточка прыгает. Нужна пружина (withSpring или Animated.spring).
  4. Ошибкастрока 11
    Эффект без зависимостей запускает анимацию на каждом рендере, а рендеров при перетаскивании десятки.
  5. Производительностьстрока 16
    HeavyContent перерисовывается при каждом движении: его нужно мемоизировать или убрать перерисовки родителя.

Разбор

Перетаскивание делают так, чтобы React не участвовал в каждом кадре: Gesture.Pan меняет shared value, useAnimatedStyle применяет сдвиг на UI-потоке, возврат через withSpring. Жест активируется только по горизонтали (activeOffsetX).

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.