You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在worklet函数中调用React useState的setter方法?

如何在worklet函数中调用React useState的setter方法?

嘿,我来帮你搞定这个问题!你遇到的核心问题是runOnJS的使用方式不对——它的正确用法是先传入要执行的JS函数,再传递该函数需要的参数,而不是直接把整个函数逻辑包裹进去。

问题根源

你之前在runOnJS里直接写了状态更新的逻辑,这个回调其实还是运行在worklet的UI线程上下文里,并没有正确切换到React的JS主线程,所以状态更新没生效,对应的console.log也可能看不到预期的输出。

修正步骤

  1. 把状态更新逻辑抽成独立的JS函数:因为worklet不能直接操作React状态,必须通过runOnJS桥接回JS主线程执行纯JS逻辑。
  2. 正确调用runOnJS:先传入你定义的状态更新函数,再传递该函数需要的参数(比如这里的newItem)。

修正后的完整代码片段

import {runOnJS} from 'react-native-reanimated';

// 单独定义JS线程的状态更新函数
const addDuctItem = (newItem) => {
  setDuctItems((prevDuctItems) => {
    const updatedDuctItems = [...prevDuctItems, newItem];
    console.log('Updated ductItems:', updatedDuctItems);
    return updatedDuctItems;
  });
};

const handleDragEnd: DndProviderProps['onDragEnd'] = ({active, over}) => {
  'worklet';

  if (over) {
    console.log('onDragEnd', {active, over});
    console.log(active);

    const newItem = {
      partName: `${active.id.split('-')[0]}`,
    };

    // 正确调用runOnJS:先传函数,再传参数
    runOnJS(addDuctItem)(newItem);

    dynamicData.value = {
      over: over,
    };
  }
};

return (
  <GestureHandlerRootView>
    <View style={styles.container}>
      <DndProvider
        onDragEnd={handleDragEnd}
      >
        <Droppable id="drop" style={styles.dropBox}>
          <Text>DROP</Text>
        </Droppable>
        <View style={styles.partsContainer}>
          <Text>{JSON.stringify(ductItems)}</Text>
          {ductItems.map((item, index) => (
            <DraggableCustomComponent
              style={styles.partItem}
              id={`${item.partName}-${index}-key`}
              key={`${item.partName}-${index}-key`}
              partType={item.partName}
              data={dynamicData}
            />
          ))}
        </View>
      </DndProvider>
    </View>
  </GestureHandlerRootView>
);

额外注意事项

  • 确保runOnJS从react-native-reanimated正确导入,版本也要适配(v2+的用法都是这样)。
  • worklet函数里不能直接访问React的状态或setter,所有需要操作React状态的逻辑都要放在JS线程的函数里,通过runOnJS调用。
  • 如果你的参数(比如newItem)是在worklet里生成的,一定要作为参数传递给JS函数,因为worklet和JS环境的作用域是完全隔离的。
  • React状态更新是异步的,如果你在调用setDuctItems后立刻读取ductItems,拿到的还是旧值,要依赖setDuctItems的回调或者useEffect监听ductItems的变化来处理后续逻辑。

备注:内容来源于stack exchange,提问作者Brian Var

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 11:55:26