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