React native run useState/force rerender внутри функции worklet

Я звоню useAnimatedScrollHandlerперехватчик от react-native-reanimated для обработки моих onScroll функционировать на Animated.ScrollView. Этот хук работает так, как ожидалось, но теперь я хочу отключить настраиваемую кнопку (My FlatButton) на основе currentIndex который является sharedValue. Но когда sharedValue изменяется, экран не перерисовывается, потому что состояние не меняется, поэтому внешний вид моей кнопки остается прежним.
Есть ли способ принудительно выполнить повторную визуализацию внутри рабочеголета или можно использовать useState принудительно выполнить повторную визуализацию изнутри worklet?

      const scrollHandler = useAnimatedScrollHandler((event) => {
  translationX.value = event.contentOffset.x
  if (event.contentOffset.x < width * 0.5 && currentIndex.value != 0) {
    currentIndex.value = 0
  } else if (
    event.contentOffset.x > width * 0.5 &&
    event.contentOffset.x < width * 1.5 &&
    currentIndex.value != 1
  ) {
    currentIndex.value = 1
  } else if (event.contentOffset.x > width * 1.5 && currentIndex.value != 2) {
    currentIndex.value = 2
  }
})
      <FlatButton
  label="Next"
  disabled={
    (currentIndex.value == 0 && (!firstName || !lastName)) ||
    (currentIndex.value == 1 && (!dateOfBirth || !sex)) ||
    (currentIndex.value == 2 &&
      (!streetNumber || !postalCode || !city || !state || !country))
  }
  onPress={() => {
    if (currentIndex.value == 0) {
      scrollRef.current
        ?.getNode()
        .scrollTo({ x: width, animated: true })
    } else if (currentIndex.value == 1) {
      scrollRef.current?.getNode().scrollToEnd({ animated: true })
    }
  }}
/>

1 ответ

Я только что узнал, что предлагает функцию reanimatedrunOnJS, которая позволяет запускать функцию javscript, например setStateвнутри рабочего листа. Так что просто создайте функцию-оболочку, как в моем случае toggleIndex в котором вы взаимодействуете со своим состоянием и вызываете эту функцию внутри runOnJS из вашего рабочего листа.

      const [currentIndex, setCurrentIndex] = useState(0)

const toggleIndex = (index: number) => {
  setCurrentIndex(index)
}

const scrollHandler = useAnimatedScrollHandler((event) => {
  translationX.value = event.contentOffset.x
  if (event.contentOffset.x < width * 0.5 && currentIndex != 0) {
    runOnJS(toggleIndex)(0)
  } else if (
    event.contentOffset.x > width * 0.5 &&
    event.contentOffset.x < width * 1.5 &&
    currentIndex != 1
  ) {
    runOnJS(toggleIndex)(1)
  } else if (event.contentOffset.x > width * 1.5 && currentIndex != 2) {
    runOnJS(toggleIndex)(2)
  }
})
Другие вопросы по тегам