React-Apollo突变writeQuery不会更新ui

时间:2019-07-26 22:20:00

标签: reactjs graphql react-apollo apollo-client

我通过howtographql.com学习GraphQL,但是当使用变异进行投票时,UI不会更新。我在商店上使用readQuery和writeQuery,搜索后我测试在客户端上使用readQuery和writeQuery,但不再起作用。

包装使用和版本:
├─apollo-boost@0.4.3
├─apollo-cache-inmemory@1.6.2
├─apollo-cache@1.3.2
├─apollo-client@2.6.3
├─apollo-link-context@1.0.18
├─apollo-link-error@1.1.11
├─apollo-link-http-common@0.2.14
├─apollo-link-http@1.5.15
├─apollo-link@1.2.12
├─apollo-utilities@1.3.2
├─react-apollo@2.5.8

LinkList.js

import React, { Component } from 'react';
import Link from './Link';
import { Query } from 'react-apollo';
import gql from 'graphql-tag';

export const FEED_QUERY = gql`
    {
        feed {
            links {
                id
                createdAt
                url
                description
                postedBy {
                    id
                    name
                }
                votes {
                    id
                    user {
                        id
                    }
                }
            }
        }
    }
`

class LinkList extends Component {
    _updateCacheAfterVote = (store, createVote, linkId) => {
        const data = store.readQuery({ query: FEED_QUERY })

        const votedLink = data.feed.links.find(link => link.id === linkId)
        votedLink.votes = createVote.link.votes

        store.writeQuery({ query: FEED_QUERY, data })
    }
    render() { 
        return (
            <Query query={FEED_QUERY}>
                {({ loading, error, data }) => {
                    if (loading) return <div>Fetching</div>
                     if (error) return <div>Error</div>

                    const linksToRender = data.feed.links

                    return (
                        <div>
                            {linksToRender.map((link, index) => (
                                <Link
                                    key={link.id} 
                                    link={link} 
                                    index={index} 
                                    updateStoreAfterVote={this._updateCacheAfterVote}
                                />
                            ))}
                        </div>
                    )
                }}
            </Query>
        )
    }
}

export default LinkList

Link.js

import React, { Component } from 'react'
import { AUTH_TOKEN } from '../constants'
import { timeDifferenceForDate } from '../utils';
import { Mutation } from 'react-apollo';
import gql from 'graphql-tag';

const VOTE_MUTATION = gql`
    mutation VoteMutation($linkId: ID!) {
        vote(linkId: $linkId) {
            id
            link {
                votes {
                    id
                    user {
                        id
                    }
                }
            }
            user {
                id
            }
        }
    }
`

class Link extends Component {
    render() {
        const authToken = localStorage.getItem(AUTH_TOKEN)
        return (
            <div className="flex mt2 items-start">
                <div className="flex items-center">
                    <span className="gray">{this.props.index + 1}</span>
                    {authToken && (
                        <Mutation
                            mutation={VOTE_MUTATION}
                            variables={{ linkId: this.props.link.id }}
                            update={(store, { data: { vote } }) =>
                                this.props.updateStoreAfterVote(store, vote, this.props.link.id)
                            }
                        >
                            {voteMutation => (
                                <div className="ml1 gray fl1 pointer" onClick={voteMutation}>
                                    ▲
                                </div>
                            )}
                        </Mutation>
                    )}
                </div>
                <div className="ml1">
                    <div>
                        {this.props.link.description} ({this.props.link.url})
                    </div>
                    <div className="f6 lh-copy gray">
                        {this.props.link.votes.length} votes | by{' '}
                        {this.props.link.postedBy
                            ? this.props.link.postedBy.name
                            : 'Unknown'}{' '}
                        {timeDifferenceForDate(this.props.link.createdAt)}
                    </div>
                </div>
            </div>
        )
    }
}

export default Link

1 个答案:

答案 0 :(得分:3)

我像这样更改_updateCacheAfterVote函数,并且可以正常工作

_updateCacheAfterVote = (store, createVote, linkId) => {
    const data = store.readQuery({ query: FEED_QUERY })
    data.feed.links.find(link => link.id === linkId).votes.push(createVote)
    store.writeQuery({ query: FEED_QUERY, data })
}