将状态数据传递给 ipc 函数调用

Pass state data to ipc function call

问题

将数据发送到渲染器的事件在 chokidar 的文件更改时触发。当文件观察器被触发并且进程将事件发送到渲染器时。

我的问题是,当 EmitterEvent 被触发时,我输入 useState() 变量的当前状态,但只有初始状态被传递到我的函数。

已编辑:我的问题是我无法将更新后的 data 变量传递给从 preload.js 中的 emitter 调用的 updateData(newData) 函数。


问题

如何将状态变量 data 传递给调用?

有没有一种方法可以将 preload.js 更改为 api.receive 函数 return 字符串,从而不必将函数传递给 emitter ? (请查看 updateData(newData) 函数了解更多信息)

有没有更好的方法来实现这个?

这也可以帮助我初始化第一次渲染的数据。


preload.js

contextBridge.exposeInMainWorld(
    "api", {
        send: (channel, data) => {
            // whitelist channels
            let validChannels = ["file", "save"];
            if (validChannels.includes(channel)) {
                ipcRenderer.send(channel, data);
            }
        },
        receive: (channel, func) => {
            let validChannels = ["file", "save"];
            if (validChannels.includes(channel)) {
                // Deliberately strip event as it includes `sender` 
                ipcRenderer.on(channel, (event, ...args) => func(...args));
            }
        },
        

    }

electron.js

function ReadNodesFileToIpc(path) {
  fs.readFile(path, (error, data) => {
    win.webContents.send("file", data);
  });
}

组件中接收数据的代码

 function MyForceGraphComponent(){ 
  const [data, setData] = useState({ nodes: [{ id: 0, otherinfo: [] }], links: [] });
  var isDataInittiallized = 0;
  ...
 
  function updateData (newData, data) {
    if (data.nodes.length !== 1){ 
      // do stuff

      setData({ nodes:  data.nodes, links: data.links });
    }else{
      if (!isDataInittiallized){
        setData({ nodes:  newData.nodes, links: newData.links });
        isDataInittiallized = 1;
      }
    }
  }
  ...
  useEffect(() => {  
    ...
    window.api.receive("file", (bytesArray) => {
           var newData = JSON.parse(String.fromCharCode.apply(null, bytesArray));
           updateData(newData); // Check function bellow
              
         });
    ...
  }, []);
}

updateData(newData)(我的组件函数中的一个函数)

isDataInittiallized 是组件内部的一个变量,更改已传递给 emitter

data 是我来自 useState() 函数的变量, 所做的更改 NOT 已传递给 emitter 即使 setData() 之前已成功更改 data。所以长度保持为 1,并且它包含与第一次初始化时相同的元素。


其他信息

曾尝试将 data 变量传递给接收函数,但没有成功。

最有可能的是,当发射器被设置时,传递的函数(执行 JSON.parse 的函数)被传递并且之后从未改变。

我发现你的代码有一些错误。当你调用 updateData(newData) 时,data 为 null,data.nodes 将不起作用。你可以修改你的代码,“如果(数据 && data.nodes && data.nodes.length !== 1)"

由于问题与 updateData 函数内的陈旧数据有关,我建议进行以下更新:

// Simplified for the sake of brevity

function MyForceGraphComponent() {
  const [data, setData] = useState({ nodes: [{ id: 0 }] })

  // isDataInitialized needs to be tracked just as any other state
  const [isDataInitialized, setIsDataInitialized] = useState(false)

  // Wrap `updateData` in `React.useCallback` to prevent stale data
  const updateData = useCallback(
    (nextData) => {
      // skip the update, no need to update the state with existing data
      if (isDataInitialized) return;
    
      setData({ nodes: nextData.nodes })
      setIsDataInitialized(true) // set to `true` to prevent future updates
    }, 
    [isDataInitialized, setIsDataInitialized]
  )

  const handleReceivedData = useCallback(
    (bytesArray) => {
      const nextData = JSON.parse(...)
      updateData(nextData)
    }, 
    [updateData]
  )

  useEffect(() => {
    window.api.receive('file', handleReceivedData);
  }, [handleReceivedData])
}

看看这个模仿您正在尝试做的事情的例子: