【问题标题】:React native run useState/force rerender inside worklet funtionReact native run useState/force re render inside worklet function
【发布时间】:2021-10-18 01:31:58
【问题描述】:

我正在从react-native-reanimated 调用useAnimatedScrollHandler 挂钩来处理Animated.ScrollView 上的onScroll 函数。这个钩子按预期工作,但我现在想禁用基于currentIndex 的自定义按钮(My FlatButton),这是一个sharedValue。但是当 sharedValue 改变时,屏幕不会重新渲染,因为状态没有改变,所以我的按钮的外观保持不变。
有没有办法强制在工作集内重新渲染,或者可以使用useState 强制从工作集内重新渲染?

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

【问题讨论】:

    标签: react-native react-native-reanimated-v2


    【解决方案1】:

    我刚刚发现 reanimated 提供了 runOnJS 函数,这使得在工作集中运行像 setState 这样的 javscript 函数成为可能。因此,只需创建一个包装函数,就像在我的例子中 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)
      }
    })
    

    【讨论】:

    • 干杯,帮助我弄清楚如何使用 useState、useEffect 和 runOnJs!为我节省了大量时间。
    猜你喜欢
    • 1970-01-01
    • 2021-02-01
    • 2021-05-27
    • 1970-01-01
    • 1970-01-01
    • 2017-05-12
    • 2023-03-22
    • 2016-08-04
    • 1970-01-01
    相关资源
    最近更新 更多