Skip to content
This repository has been archived by the owner on Jul 10, 2019. It is now read-only.

Is there any way to simplify this state manager? #323

Open
sessionboy opened this issue Oct 28, 2018 · 12 comments
Open

Is there any way to simplify this state manager? #323

sessionboy opened this issue Oct 28, 2018 · 12 comments

Comments

@sessionboy
Copy link

Apollo-link-state is a great project, but it is too cumbersome to use.
Is there any way to simplify it?
Should it be simplified, it can be as simple as dva, vuex, mobx-react

@smolinari
Copy link

smolinari commented Oct 28, 2018

What is cumbersome about it? As I see it, it's simplicity of being able to use the same query system, instead of using an extra and external state manager, makes it less cumbersome.

You do realize, it is supposed to be used with Apollo Client, right?

Scott

@sessionboy
Copy link
Author

@smolinari hi guy.
I understand, but when I use Apollo-link-state, I find it is as complex as redux and I need to do a lot of work, and I just want to manage a global state. For example, I want to store login users, I have to do a lot of work. But all I want is something like this:

 ...
 const loginUser =  result;  
 const client = this.props.client;   // it is apollo's client
 client.updateState("loginUser",loginUser);    //  "loginUser"  is  __typename
 ....

Then, when I need it, I get it like this:

 ...
 const client = this.props.client;   // it is apollo's client
 client.getState("loginUser");   //  "loginUser"  is  __typename
 ....

Now, due to the complexity of apollo-link-state, I didn't use it, but instead use localStorage.

like this:

 ...
 const loginUser =  result;  
 localStorage.setItem("loginUser",loginUser);
 ...

 when i get it:

 localStorage.getItem("loginUser");
 ....

It is easy. I especially hope that apollo-link-state can be as simple as this.

@smolinari
Copy link

I want to store login users,

I'm still not sure what is difficult about doing this. How about showing your link-state code?

Scott

@cncolder
Copy link

+1

There are only single field client state in examples. visibilityFilter: String, isLike: Boolean.

When I try to store an json object into cache. I cannot find a way to do that.

const GET_PICTURES_VARIABLES = gql`
    {
        picturesVariables @client {
            sort
            limit
            skip
        }
    }
`

const GET_PICTURES = gql`
    query pictures($sort: JSON, $limit: Int, $skip: Int) {
        pictures(sort: $sort, limit: $limit, skip: $skip) {
            name
            url
        }
    }
`

const page = props => (
    <Query query={GET_PICTURES_VARIABLES}>
        {({ data: { picturesVariables } }) => (
            <Query query={GET_PICTURES} variables={picturesVariables}>
                {({ data: { pictures }, client }) => (
                    <Table
                        data={pictures}
                        page={picturesVariables.skip}
                        pageSizes={picturesVariables.limit}
                        sorted={picturesVariables.sorted}
                        onChange={({ sorted, page, pageSizes }) =>
                            client.writeData({
                                data: {
                                    picturesVariables: {
                                        sorted: sorted,
                                        limit: pageSizes,
                                        skip: page,
                                    },
                                },
                            })
                        }
                    />
                )}
            </Query>
        )}
    </Query>
)

The picturesVariables shape like this:

const defaults = {
    picturesVariables: {
        sort: { createdAt: 'desc' },
        limit: 10,
        skip: 0,
    }
}

@sessionboy
Copy link
Author

@smolinari

I want to store login users,

I'm still not sure what is difficult about doing this. How about showing your link-state code?

Scott

I know that apollo-link-state can do this, but it takes a lot of work to do. It looks more like redux, and redux is very complicated and cumbersome to use, and redux is being abandoned by users. For the user, we want to be as simple as possible. For example, dva, mobx-react, vuex, etc., they are the best state management libraries. In addition, apollo-link-state has been unpopular because it is too complicated and difficult to get started. We hope it will be easier to use, so that more people will use it.

@fbartho
Copy link
Contributor

fbartho commented Oct 30, 2018

@sessionboy, I think we’re looking for a little bit more specific feedback. Depending on the use case, we have several beginner tutorials.

Potential areas of investigation:

  • Is this something wrong with Apollo ApolloClient ApolloLink?
  • Is this something difficult about graphql’s beginner friendliness?
  • is this something wrong with the beginner guides and docs?

We’d love to help you, and others, but it sounds like you might have been trying to use link state in a harder way than normally intended. If you want to share code, we could help in a more useful way!

@fbartho
Copy link
Contributor

fbartho commented Oct 30, 2018

Based on your above snippets, it seems like you haven’t been using react-apollo or the query components. That’s the user friendlier api!

@sessionboy
Copy link
Author

Based on your above snippets, it seems like you haven’t been using react-apollo or the query components. That’s the user friendlier api!

hi guy.
I used react-apollo but didn't use apollo-link-state because it's too complicated. The above code snippet is how I want to use apollo-link-state. Like this:

//  Suppose apollo-link-state has an updateState method that can be used to update or store the state. __typename is the key.
...
 const loginUser =  result;  
 const client = this.props.client;   // it is apollo's client
 client.updateState("loginUser",loginUser);    //  "loginUser"  is  apollo's __typename
 ....

Then, when I need it, I get it like this:

//  Suppose there is a getState method that can get the state directly according to __typename
...
 const client = this.props.client;   // it is apollo's client
 client.getState("loginUser");   //  "loginUser"  is apollo's  __typename
 ....

You can make improvements like this, it's very simple to use, not as complicated as it is now.

@smolinari
Copy link

To me, the code above @sessionboy looks more complicated than using link-state, because, where are the GraphQL queries in that code? They are missing and thus, you are duplicating code unnecessarily, i.e. requesting data from the client store/ state.

If you have used link-state, show us your code. If there is any unnecessary verbosity, maybe we can show you a better way.

But, please don't come in here saying it can be improved or needs improving, without showing exactly what's wrong to begin with. Because, your suggestion for improvement has absolutely no merit without showing what you think is actually wrong. You know we need both the "this is what I see" and the "this is what I think I should see". You are only showing us the latter.

Scott

@sessionboy
Copy link
Author

To me, the code above @sessionboy looks more complicated than using link-state, because, where are the GraphQL queries in that code? They are missing and thus, you are duplicating code unnecessarily, i.e. requesting data from the client store/ state.

If you have used link-state, show us your code. If there is any unnecessary verbosity, maybe we can show you a better way.

But, please don't come in here saying it can be improved or needs improving, without showing exactly what's wrong to begin with. Because, your suggestion for improvement has absolutely no merit without showing what you think is actually wrong. You know we need both the "this is what I see" and the "this is what I think I should see". You are only showing us the latter.

Scott

Sorry, I said it is not good enough. I didn't mean to devalue apollo-link-state, in fact it was very good.
My idea is simple. Apollo-link-state depends on graphql. It must define the schema structure, query, mutation, etc., so it needs to do a lot of work.
But often our needs may be simpler, such as I want to store the login user, it is an object. I hope that without defining the schema structure, query, mutation can store it directly, and can get it without the need for a query. Just like dva, mobx-react, vuex, if you have used them.

Simply put, if you don't need to define the data structure in advance, you can freely store data of any structure, so you can use it very easily. My code snippet above describes how I want to use apollo-link-state, not the current apollo-link-state. I don't need to define the schema structure. The query is not lost, but I don't need it. The mutation is the same. .

You are interpreting my problem based on the current apollo-link-state architecture, and I am based on the architectural model of dva, mobx-react, and vuex, so there may be some misunderstandings in understanding.

@xcv58
Copy link

xcv58 commented Nov 1, 2018

I have another example to demonstrate that the current apollo-link-state architecture is hard to use.

Imaging we have a dynamic form which can add input field on the fly. And we need to maintain the input in apollo-link-state. Since all field has it's own key, and we should store it in an object. But apollo-link-state doesn't support query an object without providing keys #205.

And even we provide all possible keys (which is impossible because the user will dynamically add more input field), it requires the defaults have all fields with default value otherwise the query will fail.

All above are unnecessary steps for a simple form input state management. We can achieve this easily in Redux, mobx, etc.

@fbartho
Copy link
Contributor

fbartho commented Nov 1, 2018

Yeah, it definitely sounds like these use-cases are difficult to write in GraphQL / in a Strongly-Typed Environment. -- I myself went through the pain of implementing a Strongly Type Form-Editor Template-System (Any number of questions, of a half-dozen question types, with different editors, and default data, and different validators), I know how much I had to write to get that all working cleanly.

That said, being an "un-typed generic data-store" isn't the intended purpose of GraphQL, nor is it the purpose of apollo-link-state. -- As several people have rightly said, there are other state-managers that are looser for those kinds of use-cases. If that's a hard requirement for you, I definitely recommend checking those out.

Apollo-link-state helps people store local-state in the same cache as remote state, and makes them equally conveniently queryable -- Provided you're using the "public-facing" GraphQL to make those queries, and using Mutations to edit the state. If you don't want to go through that structure, then you're definitely going to be fighting against the intended use cases of apollo-link-state.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants