Wails中调用Go函数后状态更新不生效怎么办?

Designer°悦辰 阅读 24

我在React组件里用Wails调用Go的fetchData函数,返回数据后setState就是不更新界面,卡成加载状态了。

代码是这样的:


function App() {
  const [data, setData] = useState(null);
  
  useEffect(() => {
    wails.Events.On("dataReady", (result) => {
      console.log("Got data:", result); // 这里能正常打印数据
      setData(result); // 这行执行后界面没变化
    });
    
    wails.Go.Run("GetData").catch(err => console.error(err));
  }, []);

  return <div>{data ? JSON.stringify(data) : "Loading..."}</div>;
}

尝试过把setData包在useCallback里,也试过用forceUpdate,但都不行。控制台没报错,就是状态没变。是不是Wails的事件循环有问题?或者需要手动触发重渲染?

我来解答 赞 5 收藏
二维码
手机扫码查看
1 条解答
UP主~淑怡
这个问题其实跟Wails的事件循环没啥关系,主要是React的状态更新机制和异步事件处理的问题。React的useState是异步的,但更重要的是,wails.Events.On注册的回调函数可能不在React的上下文中执行,这会导致状态更新不触发重渲染。

推荐的做法是确保回调函数在React的上下文中运行。你可以用useEffectuseRef来解决这个问题。把事件监听器的注册逻辑放到useEffect里,并通过一个ref来存储数据,然后在useEffect中监听这个ref的变化并调用setData

下面是修改后的代码:
function App() {
const [data, setData] = useState(null);
const dataRef = useRef(null);

useEffect(() => {
const handler = (result) => {
console.log("Got data:", result);
dataRef.current = result;
setData(result); // 确保在React上下文中更新状态
};

wails.Events.On("dataReady", handler);

wails.Go.Run("GetData").catch(err => console.error(err));

return () => {
wails.Events.Off("dataReady", handler); // 清理事件监听器,避免内存泄漏
};
}, []);

return <div>{data ? JSON.stringify(data) : "Loading..."}</div>;
}


这里的关键点有两个:一是通过useEffect确保事件监听器只注册一次,并且在组件卸载时清理掉;二是直接在事件回调中调用setData,不需要额外的useCallbackforceUpdate

如果还是不行,可以检查一下你的Go代码是不是没有正确触发dataReady事件,或者返回的数据格式有问题。根据Wails官方文档,事件传递的数据应该是可以被JSON序列化的,如果数据结构太复杂可能会导致问题。

最后提醒一句,调试这种跨语言框架的时候,打印日志真的很重要,别嫌麻烦。
点赞 4
2026-02-17 11:08