#IpcRender cause a React re-render

19 messages · Page 1 of 1 (latest)

crude topaz
#

I'm having an issue that every ipcRenderer.send call cause a re-render

every time I call window.electron.ipcRenderer.send('x', ...) the render prcess get's re-redered causing an "infinite loop" kind feel

I have an App.tsx file that looks like so

  return (
    <>
      <Row rowId={1} />
      <Row rowId={2} startRange={10} endRange={20} />
      <Row rowId={3} startRange={20} endRange={30} />
    </>
  )

a Row.tsx

function Row({ startRange = 0, endRange = 0, rowId }) {
  const [isHovered, setHovered] = useState(false)

  function handleMouseEnter() {
    setHovered(true)
    window.electron.ipcRenderer.send('openModal', rowId)
  }

  function handleMouseLeave() {
    setHovered(false)
    window.electron.ipcRenderer.send('closeModal', rowId)
  }

  return (
    <div
      className={`row ${isHovered ? 'hovered' : ''}`}
      onMouseEnter={handleMouseEnter}
      onMouseLeave={handleMouseLeave}
    >
    ...
    </div>
  )
}

my main process index.js

  ipcMain.on('openModal', (_, x) => {
       // do something
    })

    ipcMain.on('closeModal', (_, x) => {
      // do something
    })

what am I doing wrong ?

topaz patrol
#

You call setHovered in your function, so of course your component rerender. It's not related to IPC at all

crude topaz
topaz patrol
#

And what's this modal?

#

Where is it?

crude topaz
#

IPC main listener

  ipcMain.on('openModal', (_, modalId) => {
      const mainCurrentPosition = main.getPosition()
      const modal = createModalWindow(mainCurrentPosition[0] + 175, mainCurrentPosition[1] + 30)
      if (!modalList.some((m) => m.modalId === modalId)) {
        modal.show()
        modalList.push({ modal, modalId })
      }
    })

modal window

function createModalWindow(x, y) {
  const modelWindow = new BrowserWindow({
    width: 195,
    height: 250,
    autoHideMenuBar: true,
    show: false,
    frame: false,
    x,
    y,
    ...(process.platform === 'linux' ? { icon } : {}),
    webPreferences: {
      preload: join(__dirname, '../preload/index.js'),
      sandbox: false
    }
  })

  return modelWindow
}
topaz patrol
#

Why do you think a rerender is the problem and not the implementation itself?

crude topaz
#

Actually I'm not sure, this was my thought process

every mouse move -> trigger mouse event -> change state + IPC call -> re-render screen loop

when removing the IPC call it didn't happend, so I assumed it has something to do

topaz patrol
#

When you remove ipc call no modal is created

#

So no problem

crude topaz
#

but I want to create a modal when the mouse is hovering each row ..
and want to remove the modal when moves moves away

#

something like so -> I'm trying to create a clone of this app called Clippy

topaz patrol
#

It's called a context menu

#

There is no reason to use a whole new renderer window for this

crude topaz
#

ok I'll take a look at the docs, thanks

crude topaz
#

@topaz patrol
any clue why my menu item isn't clickable ?

template

const isMac = process.platform === 'darwin'
const template = [
  {
    label: 'History'
  },
  {
    type: 'separator'
  },
  {
    label: 'Example',
    submenu: [
      {
        label: 'Paste',
        accelerator: isMac ? 'Cmd+V' : 'Ctrl+V',
        role: 'paste'
      }
    ]
  }
]

menu setup

const menu = Menu.buildFromTemplate(template)
    menu.popup()
topaz patrol
#

try to remove label and accelerator

#

role: 'paste' already handles this for you