Как обновить значение, полученное из запроса при нажатии кнопки в другом компоненте, с помощью react, typescript и graphql? - PullRequest
0 голосов
/ 05 мая 2020

я хочу обновить значение, которое я получил из запроса graphql при нажатии кнопки из другого компонента.

Что я пытаюсь сделать? У меня есть ButtonComponent с кнопкой «Добавить» и меткой «count», которая получает значение из запроса graphql с именем getCount.

Есть CountViewComponent с меткой «showAvailableCount», которая получает значение из того же запроса graphql с именем getCount .

Этот запрос getCount возвращает availablebookscount, availablepenscount, totalbookscount, totalpenscount и выглядит так, как показано ниже,

export const GET_COUNT = gql`
    query GetCount {
        getCount {
            totalpenscount
            totalbookscount
            availablepenscount
            avaialbalebookscount
        }
    }
`;

ButtonComponent, как показано ниже,

function ButtonComponent () {
    const { count } = useGetCount();
    const availablepenscount = count.availablepenscount;
    const onAdd = async () => {
        await createItem({ email: email, Id: id }); //this is the mutation
    };
    render = () => {
        return (
            <button onClick={onAdd}>Add</button>
            <span>Count</span>
            <span>{availablepenscount}</span>
        )
    }
}

В этом компоненте при нажатии кнопки добавления я вызываю мутацию createItem. внутри мутации createItem я обновляю кеш для availablepenscount, уменьшая значение на 1 и, следовательно, обновляя переменную Count.

мутация createItem выглядит, как показано ниже,

const createItem = (variables: CreateInput) => {
    return mutation({
        variables,
        update: (cache, {data}) => {
            if (!data) return;

        const ListCache: any = cache.readQuery({ query: LIST_ITEMS });
        ListCache.listItems.push(data.createItem);
        cache.writeQuery({ query: LIST_ITEMS, data: ListCache });
        const cacheData: any = cache.readQuery({query: GET_COUNT});
            cacheData.getCount.availablepenscount--;//updating 
            //availablepencount from cache
            cacheData.getCount.availablebookscount--;
            cache.writeQuery({
                query: GET_COUNT,
                data: cacheData,
            });
        },
    });
    return { createItem, result };
}

, и результат выглядит следующим образом ,

createItem:
    email: "some_email.com"
    id: "1"

countViewComponent выглядит, как показано ниже,

function countViewComponent () {
    const { count } = useGetCount();
    const availablepenscount = count.availablepenscount;
    render = () => {
        return (
            <span>ShowAvailable</span>
            <span>{availablepenscount}</span>
        )
    }
}

Как я могу обновить это значение showAvailableCount при нажатии кнопки «Добавить». значение переменной availablepenscount в ButtonComponent обновляется, как и ожидалось, вместе с кешем. но не работает так же в CountViewComponent.

Может ли кто-нибудь помочь мне исправить это. Я новичок в использовании машинописного текста и graphql. Спасибо.

EDIT: Здесь есть две вещи. CountViewComponent, который показывает данные из запроса GET_COUNT и ButtonComponent, который показывает те же данные, что и в CountViewCompo nnet из запроса GET_COUNT.

есть одно поле ввода. когда пользователь вводит электронную почту и нажимает кнопку добавления в ButtonComponent, вызывается мутация createItem, чтобы добавить это электронное письмо в список доступных элементов.

Когда пользователь добавляет электронную почту, это доступное значение opencount должно уменьшаться на 1.

Вместо того, чтобы снова запрашивать эти данные у сервера graphql ... я обновляю кеш во время создания мутации элемента, как видно из кода выше. ..

пока здесь все работает нормально ...

Теперь вопрос в том, что этот countViewComponent должен иметь то же значение, что и ButtonComponent после нажатия кнопки добавления ....

обновление кеша в Buttoncomponent не отображает одинаковое значение в countViewComponent ......

Как это сделать. Любая помощь приветствуется. спасибо.

Edit2: Основываясь на представленном ниже ответе, он обновляет значение счетчика в countViewComponent при нажатии кнопки добавления во второй раз

update: (cache, { data }) => {
   const cacheData: any = cache.readQuery({ query: GET_COUNT });
   cacheData.getCount.totalpenscount = 
       cacheData.getCount.totalpenscount + 0;
   cacheData.getCount.totalbookscount = 
       cacheData.getCount.totalbookscount + 0;
   cacheData.getCount.availablepenscount = 
       cacheData.getCount.availablepenscount + 1;
   cacheData.getCount.availablebookscount = 
       cacheData.getCount.availablebookscount + 0;
   cacheData.__typename = 'Count';
   cache.writeQuery({
       query: GET_COUNT,
       data: cacheData,
   });
}

1 Ответ

0 голосов
/ 06 мая 2020

Не использовать данные удаленных счетчиков ...

Кэш должен обновляться неизменными методами - путем создания новых объектов, а не путем изменения существующих. Таким образом, apollo может обнаруживать / реагировать на изменение (и принудительно обновлять наблюдаемые запросы).

    const ListCache: any = cache.readQuery({ query: LIST_ITEMS });
    ListCache.listItems.push(data.createItem);
    cache.writeQuery({ query: LIST_ITEMS, data: ListCache });

должно быть

    // concat returns a new array
    const newList: any = cache.readQuery({ query: LIST_ITEMS }).concat (data.createItem); 
    cache.writeQuery({ query: LIST_ITEMS, data: newList });

и

    const cacheData: any = cache.readQuery({query: GET_COUNT});
        cacheData.getCount.availablepenscount--;//updating 
        //availablepencount from cache
        cacheData.getCount.availablebookscount--;
        cache.writeQuery({
            query: GET_COUNT,
            data: cacheData,
        });

должно быть (что-то вроде):

    const cacheData: any = cache.readQuery({query: GET_COUNT});
    const newCounter: any = { ...cacheData.getCount }; // new object
    newCounter.availablepenscount--;//updating properties
    newCounter.availablebookscount--;
    cache.writeQuery({
        query: GET_COUNT,
        data: {
          __typename: 'Count',
          getCount: newCounter
        }
    });
...