Search code examples
relayjsrelayrelaymodern

How can I share the same form for creating and updating an object in relay-modern (experimental)?


I am new to relay and I'm attempting to use relay modern experimental in concurrent mode. I have been able to load nodes, edges, etc just fine with Suspense and ErrorBoundary. I'm now working on a form for create and update of an object.

I can't figure out how to use the same form for the create and edit cases since I won't be able to load the fragment in the create case -- where the initial values of the form fields are set to defaults. I wouldn't have anything to pass to useFragment in the create case.

How can I create an initial value that conforms to fragment definition needed by the form? Maybe there's a pattern I'm not aware of. I must be missing something. I don't want to duplicate the form UI component.


Solution

  • I don't think it makes sense to use the Relay store to drive forms in React, because it's really complicated: For example, in the create case, you would need to write the data from your form to some temporary ID that you use to identify the node in the store, and then tell the fragment container to read fields on that node. Then, in both the create or edit case, in your form input change event handlers, you would update that node using the commitLocalUpdate() API. This gets really complicated.

    A much simpler pattern for editing forms, whether you're creating a new node or editing an existing node, is to drive the form with state in your React component (useState()), and then persist (create or update) with Relay when you're done editing. In the case of a editing existing node, you end up "forking" state from the Relay store, modifying it with the form, and then persisting it. Then when the mutation completes, you update the store, either through an updater function or from fields in the mutation reply.