Generic object in graphQL mutation argument - reactjs

I'm building a GraphQL app, and all is mostly making sense so far. I've now gotten to the point where I want a modal component to delete an element.
In previous Redux apps I've made an action creator that takes in the operation, object type and the object, e.g:
this.props.openModal('delete','task',taskObject)
...however with GraphQL you need to specify exactly what schema type any mutation is expecting. Is this approach still possible? Or do I need to make a different modal mutation definition for every single object type in the app?
I guess converting it to a JSON string might do, but feels messy. So far GraphQL just seems like tons and tons of repetition, and I'm trying to keep that to a minimum, y'know?

Whelp, never mind. Apollo doesn't type-check #client mutations, so it's a non-issue for now.

Related

hydrate Relay Fragment without Query

In some parts of my app,
I have a component using a fragment.
but up the tree somewhere, i sometimes need to create temporary objects waiting to be synced with the server (once they will they are transformed as plain relay objects).
But until then, they are only a few objects passed down the tree of component.
The createFragmentContainer + some #relay(mask: false) make all this possible.
But I would like to make it a bit cleaner using useFragment.
Usefragment doesn't like at all the "fake fragment" data.
Is there a way to somewhat legibly hydrate a fragment from data not directly coming from a query?
or maybe another way?
The best idea seems to go with commitLocalUpdate
you can even create new types for your need
https://relay.dev/docs/v10.1.3/mutations/#using-updater-and-optimisticupdater

useContext with immutableJS

I have an Object of data that I store as my context. It gets filled with API responses and I feel like performance-wise I'm doing something wrong.
I tried to look into ImmutableJS but there is no reference of combining ImmutableJS with ContextAPI. Is combining them together doesn't give any benefits? And if it does do have an example of to how develop such a thing?
Whether you use context directly, add redux or pass down props through your component makes no difference to how you use immutable. ImmutableJS simply makes sure that an object does not change unintentionally and that it can be checked for changes with fast reference equality.
The problem you describe could arise from the fact that your context object changes whenever any response data is modified. Therefore it would trigger a rerender on all context consumers (see caveats). I like Immutable and use it in a large project, but if I am correct, it won't make a difference, you would have to fix the root cause or handle changes with shouldComponentUpdate.
I suggest you look into redux (or some other context provider) or show us code.
Don’t try solving your problem by introducing a dependency. It won’t be a magic bullet.
From what you describe, your context object changes frequently and is causing your component tree to rerender too often.
Maybe try creating multiple contexts that are only relevant for parts of the app. That way rerenders will only happen with subtrees using specific context.

Is it important when using React propTypes validations to check them at every level?

I'm working on a part of a React app in which a high-level component creates and passes certain props down through a few layers of components that don't use them to a final component that does.
When validating props with propTypes, is there a good reason to list these props to be checked at every level, going down through the layers? Or is it acceptable to check them only in the final component that uses them?
It seems to me that the former method is redundant; the latter seems to make more sense to me, but I'm curious if there is a reason why I ought to do the former. I haven't seen any discussion on it, which could mean it's an unimportant question, but I'd be interested to know.
I agree with you about if you use props only for dril down for children in the tree, it can be done only once at the leaf components, where you realy use this data. I recently find out that one more place is important for props validation: the components which fetch data from out of app scope, such as backend, because sometimes the structure of the data changes or the data types, then it will be dificult to find which part is broken without props validation.

React Redux - state undefined on first render

For my client I'm creating something like quiz web app in react with redux based on websockets (socket.io) with a huge, very unique data. No user interaction, just presentation layer. It works like this: I get websocket event with url to my layout and payload data, and then I render given url and fire redux action with data as argument, which becomes app's state. Simple as that. BUT I noticed that on first render initial state is loading, not given from websocket as argument to action. As I said data I get is huge and unique so I didn't want declare in reducer something like this:
pageData: {
assets: [],
questions: [],
details: []
And so on. It's much more complicated btw it's just an example. Instead of this I made something like this:
pageData: {}
And I was hoping that on view (using connect) I can get this data like this:
this.props.view.pageData.questions
But then it turned out that I can not get this because it's undefined on first render. So my questions are:
Is there a way to access to this data on first render without
declaring whole structure?
If not, should I reconstruct given data in reducer?
Should I then create reducers for each page (there are like over 20 views
with unique data)
Of course I can declare everything in reducers but I feel it's very hard to maintain so much data.
But you know, maybe I'm just too lazy and I should declare initial state for each page and this question does not have sense ;).
I think you may have a few options here:
Define fallback data in your components if undefined
Don't render your page (or components) until you have received the data
Define your initialState explicitly as you already suggested
All or most your components expect or should expect data of a certain kind and in a certain format. For this reason, laying out the structure beforehand (#3) seems to be most appropriate. Ask yourself this: would my app still display correctly if the format of the web socket event data changes?
To answer your questions specifically:
Is there a way to access to this data on first render without
declaring whole structure?
Yes, you could use the || operator in your bindings to fall back (#1) to an empty array or object or value. Example <MyComponent listOfItems={this.props.items || []}. This effectively creates an empty state, however, IMO this should be standardized in the reducer/store with initialState.
Should I then create reducers for each page[?]
Not necessarily a reducer for each page, but a store with all pertinent data to your application. It is hard to say for sure without knowing more about the architecture of your app, but keeping small, well defined chunks of information is generally easier than one big blob.
I strongly advocate defining your data beforehand. It might sound cumbersome at first, but it will pay off greatly and helps others understand what the app might look like with live data.
that's because you haven't added default case in reducer
default:
return state;

Multiple Apollo mutations

I followed the Apollo documentation to provide two mutations (createUser then signInUser) on a single React component, but one mutation (the "outer" one - signInUser) is not accessible to my code (this.props.signInUser is not a function). Maybe my server-side-enabled setup is masking one mutation, but I don't see where. Help appreciated :)
See full code here.
EDIT: same issue when using compose, see code.
You just need to name the mutations when passing them into the component, otherwise they are ALL called mutate, and override one another.
(By using the props function)
Here's a full example with named mutations:
https://gist.github.com/Siyfion/a2e9626ed431f8ff91af2c9b8cba1d67
It was caused by my apollo higher-order component which did more complex things than just calling Apollo's graphql (related to server-side rendering) and somehow must be masking properties. I bypassed this SSR behaviour for these mutations (not needed), see code.

Resources