Eli*_*eal 1 javascript apollo graphql react-redux
在下面的(未经测试的)示例代码中,如果我想访问内部 Apollo GraphQL 客户端的实例actions/math.js,我必须将其从Calculator组件传递到事件处理程序,然后从WrappedCalculator事件处理程序传递到操作创建者。
这会导致大量代码膨胀。
actions/math.js对于操作创建者来说,访问 GraphQL 客户端实例的更好方式是什么?
示例代码:
常量/Queries.js:
const MUTATION_APPEND_TO_AUDIT_TRAIL = gql`
mutation MutationAppendToAuditTrail($mathOperation: String!, $operand1: Float!, $operand2: Float!) {
appendToAuditTrail(operation: $mathOperation, operand1: $operand1, operand2: $operand2) {
id
operation
operand1
operand2
}
}
`;
Run Code Online (Sandbox Code Playgroud)
动作/math.js:
import { INCREMENT_TOTAL_BY, MULTIPLY_TOTAL_BY } from '../constants/ActionTypes';
import { getTotal } from '../reducers';
incrementResultBy = (operand, graphQlClient) => (dispatch, getState) {
// Use selector to get the total prior to the operation.
const total = getTotal(getState());
// Send action to add a number to the total in the redux store.
dispatch({
type: types.INCREMENT_TOTAL_BY,
operand,
});
// Persist the latest user activity to the server.
graphQlClient.mutate({
mutation: MUTATION_APPEND_TO_AUDIT_TRAIL,
variables: {
mathOperation: 'ADDITION',
operand1: total,
operand2: operand,
},
});
};
multiplyResultBy = (operand, graphQlClient) => (dispatch, getState) {
// Use selector to get the total prior to the operation.
const total = getTotal(getState());
// Send action to multiply the total in the redux store by a number.
dispatch({
type: types.MULTIPLY_TOTAL_BY,
operand,
});
// Persist the latest user activity to the server.
graphQlClient.mutate({
mutation: MUTATION_APPEND_TO_AUDIT_TRAIL,
variables: {
mathOperation: 'MULTIPLICATION',
operand1: total,
operand2: operand,
},
});
};
export { incrementResultBy, multiplyResultBy };
Run Code Online (Sandbox Code Playgroud)
组件/Calculator.jsx
import React from 'react';
import ApolloClient from 'apollo-client';
const Calculator = ({
total,
operand,
onPlusButtonClick,
onMultiplyButtonClick,
}) => (
<div>
<h2>Perform operation for {total} and {operand}</h2>
<button id="ADD" onClick={onPlusButtonClick(() => this.props.operand, this.props.client)}>ADD</button><br />
<button id="MULTIPLY" onClick={() => onMultiplyButtonClick(this.props.operand, this.props.client)}>MULTIPLY</button><br />
</div>
);
DisplayPanel.propTypes = {
// Apollo GraphQL client instance.
client: React.PropTypes.instanceOf(ApolloClient),
// Props from Redux.
total: React.PropTypes.number,
operand: React.PropTypes.number,
onPlusButtonClick: React.PropTypes.func,
onMultiplyButtonClick: React.PropTypes.func,
};
export default Calculator;
Run Code Online (Sandbox Code Playgroud)
容器/WrappedCalculator.js
import { connect } from 'react-redux';
import Calculator from '../components/Calculator';
import { incrementResultBy, multiplyResultBy } from '../actions';
import { getTotal, getOperand } from '../reducers';
const mapStateToProps = state => ({
total: getTotal(state),
operand: getOperand(state),
});
const mapDispatchToProps = dispatch => ({
onPlusButtonClick: (operand, graphQlClient) => dispatch(incrementResultBy(operand, graphQlClient)),
onMultiplyButtonClick: (operand, graphQlClient) => dispatch(multiplyResultBy(operand, graphQlClient)),
});
// Generate Apollo-aware, redux-aware higher-order container.
const WrappedCalculator = compose(
withApollo,
connect(mapStateToProps, mapDispatchToProps),
)(Calculator);
export default WrappedCalculator;
Run Code Online (Sandbox Code Playgroud)
我为传递 ApolloClient 实例所做的一件事是将 ApolloClient 包装在 Provider 中,如下所示:
ApolloClientProvider.js
class ApolloClientProvider {
constructor() {
this.client = new ApolloClient({
networkInterface: '/graphql'
})
}
}
export default new ApolloClientProvider()
Run Code Online (Sandbox Code Playgroud)
这将创建一个类似于 ApolloClient 的单例实例,无论您从何处引用它,都将返回首次引用 ApolloClientProvider 时初始化的相同 ApolloClient。
import ApolloClientProvider from 'ApolloClientProvider'
const client = ApolloClientProvider.client
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3264 次 |
| 最近记录: |