mui / toolpad

Toolpad: Full stack components and low-code builder for dashboards and internal apps.
https://mui.com/toolpad/
MIT License
1.27k stars 282 forks source link

Infinite loop with unstable Text Field defaultValue #2210

Open Janpot opened 1 year ago

Janpot commented 1 year ago

Duplicates

Latest version

Steps to reproduce πŸ•Ή

Steps:

  1. put a TextField on the canvas
  2. bind the defaultValue prop to String(Date.now())
  3. observe infinite loop

Page yml with reproduction:

apiVersion: v1
kind: page
spec:
  id: JxyXxRJ
  title: page1
  display: shell
  content:
    - component: PageRow
      name: pageRow
      children:
        - component: TextField
          name: textField
          props:
            defaultValue:
              $$jsExpression: |
                String(Date.now())

Current behavior 😯

The input goes in an infinite loop reinitialising the default value over and over

Expected behavior πŸ€”

The default value gets initialised only once on page start

Context πŸ”¦

No response

Your environment 🌎

No response

JerryWu1234 commented 1 year ago

let me take a look.

JerryWu1234 commented 1 year ago

https://github.com/mui/mui-toolpad/blob/ad30e8fd683580de0f85b8d22828a25f7f85792b/packages/toolpad-app/src/runtime/ToolpadApp.tsx#L700

because this line caused an infinite loop. Just in case I can’t find it so that just mark it.

JerryWu1234 commented 1 year ago

@Janpot because setScopeBindings will trigger a real-time render. I tried the throttle function to limit real-time render and make a cache of many executions. image such as this picture that it needs real-time sometimes. evalJsBindings involves a lot of other functions. perhaps I'm not good at react. I would appreciate it if you can share your idea.

Janpot commented 1 year ago

perhaps I'm not good at react.

Don't worry, this binding engine is the most complex piece of Toolpad. It's basically implementing a reactive system parallel to react. Its implementation is too intertwined with react hooks, and it's up for a rewrite. I wouldn't recommend working on it if you're just starting out on the codebase. It's not unimaginable we can only solve this issue with a deep refactor.