4

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.

Duane
  • 191
  • 9

1 Answers1

1

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.

Dmitry Minkovsky
  • 30,036
  • 20
  • 97
  • 138
  • Working with this more, I believe this is absolutely true. Thank you! – Duane Nov 03 '20 at 12:22
  • One related question - I'm using TypeScript types emitted by the relay compiler. I can see how the fragments generate types but it seems that I have to create separate TypeScript types when I want to work with the nodes outside of relay. For example, if I am adding information when laying out nodes in a canvas. Is there a better way to handle this apart from having separate types? – Duane Nov 03 '20 at 13:41
  • 1
    Glad I could help. I spent a lot of time trying to drive forms off the Relay Store before I realized it probably wasn't the way to go. RE: TS, sadly I never had a chance to use it with Relay, so I don't know what kind of types it emits (ironically, I am using the Apollo TS generator these days, and was wondering how the types it emits vary from those emitted by Relay). But in terms of extending TS types in general... I think the options are (i) creating a new interface that `extends` the Relay type, (ii) creating a new type and using `&` on the one generated by Relay, (iii) declaration merging – Dmitry Minkovsky Nov 03 '20 at 14:03