Apollo / GraphQl - Мутация одного объекта не обновляет кеш (база данных обновлена) - PullRequest
0 голосов
/ 02 ноября 2019

У меня проблема с интеграцией apollo / graphql в новый проект.

У меня есть компонент, BrandsList, который отображает бренд. С помощью этого компонента вы можете нажать на Бренд, чтобы перейти к форме обновления для каждого бренда, чтобы обновить информацию.

Вот форма обновления:

import React, { useState, useEffect } from "react";
import { graphql } from "react-apollo";
import gql from "graphql-tag";
import { UPDATE_BRAND } from "./../../../api/brands/mutations";
import { Form, Button, Dropdown, TextArea } from "semantic-ui-react";
import { useQuery, useMutation } from "@apollo/react-hooks";

const brandQuery = gql`
    query Brand($brandId: String) {
        brand(_id: $brandId) {
            _id
            name
            url
            description
            brandType
            openingDate
            closingDate
            origin
            region
            address
        }
    }
`;

const UpdateBrand = props => {
    const [values, setValues] = useState({
        _id: "",
        name: "",
        url: "",
        description: "",
        origin: "",
        region: "",
        brandType: "",
        openingDate: "",
        closingDate: "",
        address: ""
    });

    const onChange = e => {
        const { name, value } = e.target;
        setValues({ ...values, [name]: value });
    };

    const { loading, error, data, refetch } = useQuery(brandQuery, {
        variables: { brandId: props.match.params.brandId }
    });

    useEffect(() => {
        if (data) {
            setValues({ ...data.brand });
        }
    }, [data]);

    const [updateBrand, { brand }] = useMutation(UPDATE_BRAND);

    const onChangeDropDown = (e, { value }) =>
        setValues({ ...values, brandType: value });

    const onSubmit = e => {
        e.preventDefault();
        let {
            _id,
            name,
            url,
            description,
            origin,
            region,
            brandType,
            openingDate,
            closingDate,
            address
        } = values;

        updateBrand({
            variables: {
                brandId: _id,
                name,
                url,
                description,
                origin,
                region,
                brandType,
                openingDate,
                closingDate,
                address
            }
        })
        .then(() => props.history.push("/admin/brands"))
        .catch(err => console.log(err));

    };


    return (
        <div className="createBrand">
            <h1>Add a Brand</h1>
            /* BORING STATE CONTROLLED FORM  */
                <Button type="submit" form="createBrandForm">
                    Update
                </Button>
            </Form>
        </div>
    );
};

export default UpdateBrand;

Обычно все работает хорошо, не уверен, чтоиспользование useEffect для получения результата запроса в моем локальном состоянии является наиболее эффективным, но это работает. Я могу изменить свою форму и повторно отправить ее, и данные будут изменены в базе данных. Однако, когда я возвращаюсь в / admin / бренды благодаря props.history.push, данные не обновляются, и мне приходится выполнять полное обновление.

Мой распознаватель мутаций выглядит так:

updateBrand(obj, args, context) {
    if (!context.user || !context.user.isAdmin) {
        throw new Error("You have to be an admin to update a brand");
    } else if (context.user.isAdmin) {
        let {
            brandId,
            name,
            url,
            description,
            origin,
            region,
            brandType,
            openingDate,
            closingDate,
            address
        } = args;
        Brands.update(
            { _id: brandId },
            {
                $set: {
                    name,
                    url,
                    description,
                    origin,
                    region,
                    brandType,
                    openingDate,
                    closingDate,
                    address
                }
            }
        );
        return Brands.findOne({ _id: brandId });
    }
},

Итак, согласно документации, я возвращаю обновленный единственный объект, который должен вызвать обновление кэша для модификации одного объекта. Однако это не так. Любые идеи о том, как обновлять данные после каждой модификации?

Вот код мутации:

export const UPDATE_BRAND = gql`
    mutation updateBrand(
        $brandId: String!
        $name: String!
        $url: String
        $description: String
        $origin: String
        $region: String
        $brandType: String
        $openingDate: String
        $closingDate: String
        $address: String
    ) {
        updateBrand(
            brandId: $brandId
            name: $name
            url: $url
            description: $description
            origin: $origin
            region: $region
            brandType: $brandType
            openingDate: $openingDate
            closingDate: $closingDate
            address: $address
        ) {
            _id
        }
    }
`;

и здесь часть схемы:

type Mutation {
    createBrand(
        name: String!
        url: String
        description: String
        origin: String
        region: String
        brandType: String
        openingDate: String
        closingDate: String
        address: String
    ): Brand
    updateBrand(
        brandId: String!
        name: String!
        url: String
        description: String
        origin: String
        region: String
        brandType: String
        openingDate: String
        closingDate: String
        address: String
    ): Brand
    deleteBrand(brandId: String!): Boolean
}

Ответы [ 2 ]

0 голосов
/ 03 ноября 2019

Моя ошибка была в моем коде запроса graphQL для мутации обновления, предложенной @Herku. Я только отправлял обратно _id после обновления, а не остальные данные. Изменение на следующее решило проблему:

export const UPDATE_BRAND = gql`
    mutation updateBrand(
        $brandId: String!
        $name: String!
        $url: String
        $description: String
        $origin: String
        $region: String
        $brandType: String
        $openingDate: String
        $closingDate: String
        $address: String
    ) {
        updateBrand(
            brandId: $brandId
            name: $name
            url: $url
            description: $description
            origin: $origin
            region: $region
            brandType: $brandType
            openingDate: $openingDate
            closingDate: $closingDate
            address: $address
        ) {
            _id
            name
            url
            description
            origin
            region
            brandType
            openingDate
            closingDate
            address
        }
    }
`;
0 голосов
/ 02 ноября 2019

Запрос списка должен быть обновлен вручную:

https://www.apollographql.com/docs/react/data/mutations/#making-all-other-cache-updates

...