重复使用突变而不重复Apollo + React中的代码?

时间:2018-05-05 14:27:44

标签: reactjs apollo

我在React Component中有以下变异。我将需要在多个组件和不同页面上进行相同的变异。

如何重复使用我的变异代码而不重复它?

这个例子并不复杂,但有些查询使用乐观的UI并写入商店。

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 :(得分:1)

为包含gql选项和乐观UI逻辑的变异/查询创建高阶组件(HOC):

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>}/>
}