我非常喜欢让组件请求自己的数据的graphQL模式,但是一些数据属性的计算成本很高,所以我想本地化逻辑(和代码)来实现这一点。
function CheaterList({ data: { PlayerList: players } }) {
return (
<ul>
{players && players.map(({ name, isCheater }) => (
<li key={name}>{name} seems to be a {isCheater ? 'cheater' : 'normal player'}</li>
))}
</ul>
);
}
export default graphql(gql`
query GetList {
PlayerList {
name,
isCheater
}
}
`)(CheaterList);
架构如下:
type Queries {
PlayerList: [Player]
}
type Player {
name: String,
kills: Integer,
deaths: Integer
}
所以我想将isCheater
属性添加到Player并使其代码为:
function computeIsCheater(player: Player){
// This is a simplified version of what it actually is for the sake of the example
return player.deaths == 0 || (player.kills / player.deaths) > 20;
}
我该怎么做?
另一种表达方法是:如何让isCheater属性看起来好像来自后端? (但是,如果应用了乐观更新,则该函数应重新运行新数据)
答案 0 :(得分:2)
只要您使用Apollo 2.0,就可以将apollo-link-state
用作outlined in the docs。
修改您的客户端配置以包含apollo-link-state
:
import { withClientState } from 'apollo-link-state';
const stateLink = withClientState({
cache, //same cache object you pass to the client constructor
resolvers: linkStateResolvers,
});
const client = new ApolloClient({
cache,
link: ApolloLink.from([stateLink, new HttpLink()]),
});
定义仅限客户的解析器:
const linkStateResolvers = {
Player: {
isCheater: (player, args, ctx) => {
return player.deaths == 0 || (player.kills / player.deaths) > 20
}
}
}
在查询中使用@client指令
export default graphql(gql`
query GetList {
PlayerList {
name
kills
deaths
isCheater @client
}
}
`)(CheaterList);
但是,似乎在单个查询中组合本地和远程字段目前已被破坏。您可以跟踪一个未解决的问题here。