在 Apollo + React 中重用突变而不复制代码?



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

如何在不重复的情况下重复使用我的突变代码?

此示例并不复杂,但某些查询使用乐观 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);

为包含 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>}/>
}

最新更新