rjsf-team / react-jsonschema-form

A React component for building Web forms from JSON Schema.
https://rjsf-team.github.io/react-jsonschema-form/
Apache License 2.0
13.8k stars 2.16k forks source link

Custom widget access to form Data #4192

Open zzph opened 1 month ago

zzph commented 1 month ago

Prerequisites

What theme are you using?

core

Version

5.x

Current Behavior

Inside my custom widget, it will not let me access the current formData. So I pass it into formContext but that breaks the form (nothing can be inputted).

Expected Behavior

Inside my custom widget, I can access all the current values of the form

Steps To Reproduce

  1. Using react and rjsf (both on latest)
  2. Using a custom widget (as implemented per docs)
  3. I expect the formData to appear as a prop, but it does not, so I try passing it on formContext instead (as per issue here
  4. Using that formContext freezes the entire form and nothing can be inputted.

I simplified my code as per below (CodeSandbox here):

import { useState } from 'react'
import Form from '@rjsf/core';
import validator from '@rjsf/validator-ajv8';

const TestCmp = (props) => {
  const { formContext } = props;
  // Use formData as needed
  // ...
  return <div> TEST {JSON.stringify(formContext)} </div>
};

const uiSchema = {
  name: {
    'ui:widget': 'TestCmp'
  }
};
const schema = {
  "type": "object",
  "properties": {
    "name": {
      "type": "string"
    },
    "age": {
      "type": "number"
    }
  }
}

const widgets = {
  TestCmp
};

export default function Create() {
  const [formDataPublic, setFormDataPublic ] = useState({})
  return <Form
        schema={schema}
        validator={validator}
        uiSchema={uiSchema}
        widgets={widgets}
        onChange={({formData})=> setFormDataPublic(formData)}
        formContext={{formDataPublic}}
      />
}

Environment

- OS: MacOS
- Node: 20.11
- npm: 10.2.4

Anything else?

No response

zzph commented 1 month ago

Any ideas on this? I'm blocked from using this awesome library because of it

heath-freenome commented 4 weeks ago

The widget has access to the formData at its current level (in your example the widget will get the value for name) via the value prop. Is there a reason why you need access to all of the formData within a single widget?

zzph commented 4 weeks ago

Thanks for the reply.

In this case, the field would “auto suggest” a value based on other fields (which can also be corrected by the user if not correct).

Is that clear? Is there a way to achieve it?

On Sat, 18 May 2024 at 5:38 am, Heath C @.***> wrote:

The widget has access to the formData at its current level (in your example the widget will get the value for name) via the value prop. Is there a reason why you need access to all of the formData within a single widget?

— Reply to this email directly, view it on GitHub https://github.com/rjsf-team/react-jsonschema-form/issues/4192#issuecomment-2118259344, or unsubscribe https://github.com/notifications/unsubscribe-auth/AUBXB72LVJNDJYNTNXQCALLZCZMDNAVCNFSM6AAAAABHRPO5VGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCMJYGI2TSMZUGQ . You are receiving this because you authored the thread.Message ID: @.***>

heath-freenome commented 3 weeks ago

@zzph I'm wondering if the "freezing" of the form you are seeing is a situation where your the state change causes a rerender infinite loop. Theoretically, you should be able to put anything into the formContext. Have you debugged why you things are freezing?

zzph commented 2 weeks ago

Yes I've debugged, and it does seem like you're saying- it re-renders the entire component everytime 'formContext' changes. So this is an issue.

Can you suggest a work around?

heath-freenome commented 2 weeks ago

Maybe you can process the formData on change in a way that you transform what you put into the formContext is only what you need to provide the auto-suggest? Meaning if your component looks at the value of age to auto-suggest the value of name (from your example), perhaps precompute the suggestion OUTSIDE of the component and pass in the suggestion rather than the formData in the formContext?