Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/blackberry/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带有GraphQL Apollo客户端的订阅组件_Graphql_Apollo_Apollo Client_Subscriptions_Graphql Subscriptions - Fatal编程技术网

带有GraphQL Apollo客户端的订阅组件

带有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

我有一个应用程序,其中一个订阅已在使用subscribeToMore

查询组件:

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>
    );
}}