Повторно использовать мутации без дублирования кода в Apollo + React? - PullRequest
0 голосов
/ 05 мая 2018

У меня есть мутация ниже в React Component. Мне понадобится одна и та же мутация в нескольких компонентах и ​​на разных страницах.

Как я могу повторно использовать мой код мутации, не повторяя его?

Этот пример не так сложен, но некоторые запросы используют оптимистичный интерфейс и записывают данные в хранилище.

import React from 'react';
import { graphql, compose } from 'react-apollo';
import { gql } from 'apollo-boost';

const JoinLocation = props => {
    if (props.ME.loading) return null;
    const { locationMachineName } = props;
    const me = props.ME.me;
    const submit = () => {
        props
            .JOIN_LOCATION({
                variables: {
                    userId: me.id,
                    locationMachine: locationMachineName,
                },
            })
            .catch(err => {
                console.error(err);
            });
    };
    return <button onClick={() => submit()}>Join location</button>;
};

const ME = gql`
    query me {
        me {
            id
        }
    }
`;

const JOIN_LOCATION = gql`
    mutation joinLocation($userId: ID!, $locationId: ID!) {
        joinLocation(userId: $userId, locationId: $locationId) {
            id
        }
    }
`;

export default compose(
    graphql(JOIN_LOCATION, { name: 'JOIN_LOCATION' }),
    graphql(ME, { name: 'ME' }),
)(JoinLocation);

1 Ответ

0 голосов
/ 07 мая 2018

Создание компонента высшего порядка (HOC) для мутации / запроса, который содержит параметры gql и оптимистическую логику пользовательского интерфейса:

const JOIN_LOCATION = gql`
    mutation joinLocation($userId: ID!, $locationId: ID!) {
        joinLocation(userId: $userId, locationId: $locationId) {
            id
        }
    }
`;

export const withJoinLocation = component => graphql(JOIN_LOCATION, { name: 'JOIN_LOCATION' })(component);

Затем оберните его различными компонентами.

export default withJoinLocation(JoinLocation);

ОБНОВЛЕНИЕ: Исходя из вашего комментария ниже, если вы хотите инкапсулировать всю логику отправки, а не только мутацию, как указано в вашем вопросе, вы можете использовать реквизит рендеринга следующим образом:

import React from 'react';
import { graphql, compose } from 'react-apollo';
import { gql } from 'apollo-boost';

const JoinLocation = props => {
    if (props.ME.loading) return null;
    const { locationMachineName } = props;
    const me = props.ME.me;
    const submit = () => {
        props
            .JOIN_LOCATION({
                variables: {
                    userId: me.id,
                    locationMachine: locationMachineName,
                },
            })
            .catch(err => {
                console.error(err);
            });
    };
    return props.render(submit);
};

const ME = gql`
    query me {
        me {
            id
        }
    }
`;

const JOIN_LOCATION = gql`
    mutation joinLocation($userId: ID!, $locationId: ID!) {
        joinLocation(userId: $userId, locationId: $locationId) {
            id
        }
    }
`;

export default compose(
    graphql(JOIN_LOCATION, { name: 'JOIN_LOCATION' }),
    graphql(ME, { name: 'ME' }),
)(JoinLocation);

Теперь любой компонент может использовать логику повторного использования. Предположим, вы назвали вышеуказанный компонент JoinLocation.js:

import JoinLocation from './JoinLocation';

const Comp = () => {
  return <JoinLocation render={submit => <button onClick={() => submit()}>Join location</button>}/>
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...