复活的 SharedValue 更改时调用 React Native 代码

Posted

技术标签:

【中文标题】复活的 SharedValue 更改时调用 React Native 代码【英文标题】:Call React Native code when reanimated SharedValue changes 【发布时间】:2021-10-28 18:26:59 【问题描述】:

我有一个reanimated ReadOnly<SharedValue<boolean>> 是从另一个SharedValue 派生的:

  const solidHeader = useDerivedValue(() => 
    return top.value <= -(height / 2);
  );

solidHeader.value 发生变化时,我想调用一个 RN 函数(未恢复)。具体来说,我想更新我的react-navigation 的标题透明度:

// This doesn't get called when `solidHeader.value` is updated in reanimated's thread
useEffect(() => 
  navigation.setOptions(headerTransparent: !solidHeader.value);
, [solidHeader.value]);

我尝试了以下“似乎”是正确的方法,但后来我得到了错误

Reanimated: Animated.call node args should be an array with elements of type AnimatedNode. One or more of them are not AnimatedNodes
    useCode(() => 
      return call([solidHeader], (solidHeader) => 
        console.warn(solidHeader);
        navigation.setOptions(
          headerTransparent: !solidHeader,
        );
      );
    , [solidHeader]);

我正在实现的目标可能吗?

【问题讨论】:

【参考方案1】:

编辑:查看接受的答案。

所以这就是我最终做的 hack:我认为这是因为 Reanimated 故意避免通过 JS/Reanimated 线程进行通信,所以我必须在 JS 端“轮询”以“依赖” " 关于复活方面的变化:

  // top is a SharedValue
  const  top, height  = useHeaderMeasurements();
  const [headerTransparent, setHeaderTransparent] = useState(
    top.value >= -(height / 2)
  );

  useEffect(() => 
    // Poll 60FPS and update RN state
    const check = setInterval(() => 
      setHeaderTransparent(top.value >= -(height / 2));
    , 1000 / 60);
    return () => clearInterval(check);
  , [top]);

  useEffect(() => 
    navigation.setOptions( headerTransparent );
  , [navigation, headerTransparent]);

对于上下文:

useHeaderMeasurements 来自 react-native-collapsible-tab-view,它在引擎盖下使用 Reanimated V2 navigation.setOptions 来自react-navigation,当我们在Screen 中时,这要求我们在RN 端强制设置headerTransparent

【讨论】:

【参考方案2】:

我认为 useCode 是为 reanimated 1 而 useSharedValue 是 reanimated 2。 关注文档:Try useAnimatedReaction

【讨论】:

我尝试执行以下操作:useAnimatedReaction(() =&gt; top.value &gt;= -(height / 2), (result, previous) =&gt; if (result !== previous) navigation.setOptions( headerTransparent: result ); console.log(result); , [navigation]); 它似乎崩溃了,除非我注释掉 navigation.setOptions。似乎无法在第二个 Worklet 的主体中运行任何 JS 代码? 是的。你应该将你的 js 代码包装在 runOnJs() 中,遵循这个link 完美,成功了。我会将您的答案标记为已完成(并使用解决方案编辑答案)。

以上是关于复活的 SharedValue 更改时调用 React Native 代码的主要内容,如果未能解决你的问题,请参考以下文章

UICollectionView DataSource 方法未在 CoreData 更改时调用

使用 Angular 2 更改值时调用方法

用户更改密码时调用哪个 Windows API?挂钩这个 API 的好方法是啥?

如果在 Activity 更改时调用 onCreate 和 onStart 两者之间的区别在哪里?目的是啥?

Vue 3,在变量更改时调用 $emit

当组件从父组件动态更改时调用子组件中的方法