Where should the nested form components be in the user interface using Relay?

I have a user interface that is basically a form, but has various components for editing individual pieces of data. I want all the data on the page to be saved at the same time when the user clicks the save button. All data is contained in the type, and I have an update mutation for this type. Thus, while different child components can edit different parts of the object to be saved, the parent component will be responsible for performing one update mutation, which saves all the data.

The problem I am facing is that I am not sure where I should have state for the child components. Regardless of what, it seems, the state for them should be in the parent, so that it has it and can include it in the input object, which it passes to the mutation when it is executed. However, this leaves me in one of two places, nothing seems perfect:

  • Save the state of values โ€‹โ€‹edited by child components in the parent.
    • Problem: Relay throws a warning because I pass the state object to the child RelayContainer when it expects it to be a fragment obtained using Relay. You can see this warning and an example of this behavior in this playground . Here is the specific warning that I mean that you see when editing a field in a child component.

      Warning: RelayContainer: The expected details support, supplied in [object Object] , for receiving data using relays. This is probably a mistake if you do not intentionally pass a mock of data that matches the shape of this component fragment.

  • Let the child components retain their own state, but then also pass the values โ€‹โ€‹to the parents so that they have them to handle the save and mutation actions.
    • Problem: Duplication of state. Despite the fact that the state that is in the parental house is stored solely for the purpose of performing the mutation, it seems completely wrong to have it there and cause unnecessary visualizations for the parent. You can see an example of this option in this other playground .

I hope there is an obvious preferred way to deal with this situation, but from my search and playing with Relay, I could not determine it.

+6
source share
1 answer

First of all. Very well written question. Thanks: -)

The general model used in the React and Relay world is that we have a parent component that works with the thin view controller, retrieves data using Relay, and passes its state different parts as props to different child components as needed. Detailed components that accept data as props are usually dumb and simply display the transmitted data.

In your case, ChildComponent itself edits the data. It gets the initial details data from its parent HelloApp component. However, when we edit any of the details fields in the user interface, the values โ€‹โ€‹obtained using Relay and the values โ€‹โ€‹in the user interface do not match. When creating a Relay container for a child component, if we include fragments and fields, we declare that the relay will retrieve this data. Now , if we want to change the data of the child components (details) ourselves, we just skip this fragment in the Relay container. props passed by the parent component will only be used for the initialState child component.

The necessary changes are in the HelloApp container. Details fields are moved from a child to a parent.

 HelloApp = Relay.createContainer(HelloApp, { fragments: { person: () => Relay.QL` fragment on Person { name, details { hairColor, nickName } } `, } }); 

BUT I still feel uncomfortable with the above solution. Because this clearly shows that the parent needs to know the details fields that are actually used in the child components.

+3
source

All Articles