带有GraphQL Apollo客户端的订阅组件
我有一个应用程序,其中一个订阅已在使用subscribeToMore 查询组件:带有GraphQL Apollo客户端的订阅组件,graphql,apollo,apollo-client,subscriptions,graphql-subscriptions,Graphql,Apollo,Apollo Client,Subscriptions,Graphql Subscriptions,我有一个应用程序,其中一个订阅已在使用subscribeToMore 查询组件: export default class MessageList extends React.Component { componentDidMount() { this.props.subscribeToMore({ document: MESSAGE_CREATED, updateQuery: (prev, { subscriptionData }) => { if (!s
export default class MessageList extends React.Component {
componentDidMount() {
this.props.subscribeToMore({
document: MESSAGE_CREATED,
updateQuery: (prev, { subscriptionData }) => {
if (!subscriptionData.data) return prev;
return {
allMessages: [
subscriptionData.data.messageCreated,
...prev.allMessages
],
};
},
});
}
render() {
return (
<div>
{this.props.messages.map(message => (
<MessageElement key={message.id}
message={message}/>
))}
</div>
);
}}
{({data,subscribeToMore})=>{
返回(
);
}}
该查询加载一个消息列表,据我所知,我们将订阅服务器附加到ComponentDidMount中,因此每当我在查询中的列表中添加新元素时,我的订阅将侦听订阅并执行我想要的任何操作(在本例中,将新消息添加到我当前的消息列表中)
邮件组件列表:
export default class MessageList extends React.Component {
componentDidMount() {
this.props.subscribeToMore({
document: MESSAGE_CREATED,
updateQuery: (prev, { subscriptionData }) => {
if (!subscriptionData.data) return prev;
return {
allMessages: [
subscriptionData.data.messageCreated,
...prev.allMessages
],
};
},
});
}
render() {
return (
<div>
{this.props.messages.map(message => (
<MessageElement key={message.id}
message={message}/>
))}
</div>
);
}}
导出默认类MessageList扩展React.Component{
componentDidMount(){
this.props.subscribeToMore({
文档:创建的消息,
updateQuery:(prev,{subscriptionData})=>{
如果(!subscriptionData.data)返回上一个值;
返回{
所有信息:[
subscriptionData.data.messageCreated,
…上一页所有消息
],
};
},
});
}
render(){
返回(
{this.props.messages.map(message=>(
))}
);
}}
我想添加另一个订阅,因此如果我编辑我的邮件,信息将实时更新。为了实现这一点,我使用订阅创建了以下组件
消息组件(我想在其中根据更新的消息添加另一个订阅)
导出默认类MessageElement扩展组件{
componentDidMount(){
this.messageUpdatedSubscription();
}
messageUpdatedSubscription=()=>(
{({data:{messageUpdated}}})=>(
console.log('Do smthg???,messageUpdated)
)}
);
render(){
返回(
{updateMessage=>(
{this.props.message.text}
{updateMessage({变量:{
id:this.props.message.id,
text:this.props.message.text,
iFavorite:!this.props.message.iFavorite});
}}/>
)}
);
}}
我在服务器上的订阅工作正常,因为我已经在查询上创建了对消息\u的订阅,并且我已在服务器上测试是否触发了对消息\u更新的订阅。但是,我无法理解为什么UI没有显示或记录任何内容,就好像它没有侦听订阅一样
我可以通过订阅组件或subscribeToMore实现这一点吗
提前感谢无法在ComponentDidMount中启动订阅组件。它必须驻留在render()生命周期方法中。它的参数可以在ComponentDidMount中使用,但不能在组件中使用 我可以想出3种可能的解决方案: 1) 您可以尝试将订阅方法放入渲染方法中。你只需要将它嵌套在你的变异组件的内部或外部 2) 您可以在该组件的父级中启动订阅组件,并将其参数(messageUpdate)向下传递给组件MessageElement。然后,您可以在ComponentDidMount中使用messageUpdate关闭道具 3) 你可以用阿波罗的高阶组件。然后,您可以在props中访问messageUpdate。(免责声明-我以前从未尝试过)
我希望这有帮助 根据我的建议,我将我的订阅嵌套到了变异中。 我还发现,由于我有一个消息列表,我只想根据我正在更新的消息触发订阅,而不是整个列表;我必须以以下方式修改后端和前端的订阅: 服务器架构
const typeDefs = gql` type Subscription {
messageUpdated(id: Int!): Message}`;
服务器解析程序
Subscription: {
messageUpdated: {
subscribe: withFilter(
() => pubsub.asyncIterator([MESSAGE_UPDATED]),
(payload, variables) => {
return payload.messageUpdated.id === variables.id;
},
),
},
}
客户端组件
const MESSAGE_UPDATED = gql` subscription messageUpdated($id: Int!){
messageUpdated(id:$id)
{
id
text
isFavorite
}}`;
export default class MessageElement extends Component{
render(){
return(<Mutation mutation={UPDATE_MESSAGE} key={this.props.message.id}>
{updateMessage => (
<div>
<div>{this.props.message.text}</div>
<Subscription subscription={MESSAGE_UPDATED}
variables={{ id: this.props.message.id }}>
{() => {
return <Star active={this.props.message.isFavorite}
onClick={() => { updateMessage({ variables: {
id: this.props.message.id,
text: this.props.message.text,
isFavorite: !this.props.message.isFavorite } });}}/>
}}
</Subscription>
</div>
)}
</Mutation>
);
}}
const MESSAGE\u UPDATED=gql`subscription messageUpdated($id:Int!){
messageUpdated(id:$id)
{
身份证件
文本
我最喜欢
}}`;
导出默认类MessageElement扩展组件{
render(){
返回(
{updateMessage=>(
{this.props.message.text}
{() => {
返回{updateMessage({变量:{
id:this.props.message.id,
text:this.props.message.text,
iFavorite:!this.props.message.iFavorite}}});}}/>
}}
)}
);
}}
您可以在以下报告中看到代码:后端、前端谢谢@cory mcaboy。最后,我用你的第一个建议解决了这个问题,将我的订阅嵌套到我的变体中。
const MESSAGE_UPDATED = gql` subscription messageUpdated($id: Int!){
messageUpdated(id:$id)
{
id
text
isFavorite
}}`;
export default class MessageElement extends Component{
render(){
return(<Mutation mutation={UPDATE_MESSAGE} key={this.props.message.id}>
{updateMessage => (
<div>
<div>{this.props.message.text}</div>
<Subscription subscription={MESSAGE_UPDATED}
variables={{ id: this.props.message.id }}>
{() => {
return <Star active={this.props.message.isFavorite}
onClick={() => { updateMessage({ variables: {
id: this.props.message.id,
text: this.props.message.text,
isFavorite: !this.props.message.isFavorite } });}}/>
}}
</Subscription>
</div>
)}
</Mutation>
);
}}