为啥订阅完成后我的数据会消失?

Posted

技术标签:

【中文标题】为啥订阅完成后我的数据会消失?【英文标题】:Why does my data disappear when a subscription goes through?为什么订阅完成后我的数据会消失? 【发布时间】:2017-09-06 05:28:48 【问题描述】:

为什么订阅完成后我的数据未定义? 我想弄清楚我的 props.data.allLocations 的 undefined 来自哪里。任何帮助将不胜感激。

//高阶组件​​

export const LocationList = graphql(

      gql`
        query ($site: ID!) 
          allLocations(
            filter: 
            site: 
              id:$site
             
          
          ) 
            id
            name
          
        
          `,


     

       options: (ownProps)=>(
         variables: 
           site: ownProps.site
         ,
       ),
      //props were injected from the JSX element
      props: props =>  

          return 
            data: props.data,
            subscribeToData: params => 
              return props.data.subscribeToMore(
                document:

                  gql`
                    subscription newLocations 
                      Location 
                        mutation
                        node 
                          id
                          name
                        
                      
                    
                   `,
                variables: 
                  //Empty for now
                  //site: props.site,
                ,
                updateQuery: (previousState, subscriptionData) => 

                  if (!subscriptionData.data) 
                                return previousState;
                            

                var newArray =[subscriptionData.data.Location.node].concat(previousState.allLocations)
                var newState =  
                  ...previousState,
                  allLocations: [
                    
                      ...subscriptionData.data.Location.node
                    ,
                      ...previousState.allLocations
                  ],

                ;

                return newState
                
              )
            ,

          
      ,
      onError: (err) => console.error(err)
            )(EntityList)

//列表组件

class EntityList extends Component 


    componentWillReceiveProps(newProps) 
    if (!newProps.data.loading) 
      console.log(newProps)
      if (this.subscription && this.props.hasOwnProperty('subscribeToData')) 
        if (newProps.data.allLocations !== this.props.data.allLocations) 
          console.log("Resubscribe")
          // if the todos have changed, we need to unsubscribe before resubscribing
          this.subscription()
         else 
          console.log('else')
          // we already have an active subscription with the right params
          return
        
      
      this.subscription = this.props.subscribeToData(newProps)

    


  render () 

    if (this.props.data.loading) 
      return (<div>Loading</div>)
    


    var Entities = [];
    for(var key in this.props.data) 

        if(this.props.data[key] instanceof Array)
          Entities = Entities.concat(this.props.data[key])

          //console.log(this.props.data[key])
        
      


    return (
      <div className='w-100 flex justify-center bg-transparent db'  >
        <div className='w-100 db' >
          Entities.map((entity) =>

           ( 
              <EntityListView 
                user=this.props.user 
                key=entity.id 
                entityId=entity.id 
                name=entity.name 
                profilePic=(entity.profilePic)?entity.profilePic.uuid : this.props.defaultPic.uuid 
                clickFunc=this.props.clickFunc
              /> 
            )) 

        </div>
      </div>
    )
  

【问题讨论】:

请确保代码格式正确!在调用graphql 之前将调用gql 的结果提取到单独的变量中,然后只在调用中引用这些变量以使其更具可读性,这可能是一个好主意。另外,请提供有关确切错误消息的更多信息,否则将很难提供帮助。 谢谢,我实际上没有收到任何错误消息。当我将订阅功能添加到道具中时,注入的数据道具消失了,所以我将它添加到我自己的数据对象中,并使用数据:props.data。但是现在当我订阅时,我从数据中丢失了 allLocations 属性。也许我误解了更新查询返回的内容,因为我认为它会给我一个数据对象。 另外,我已经能够通过在较低组件中调用我的订阅查询来让订阅工作,但我认为这会降低我的代码的可重用性,因为我将多次重复这个过程数据模型。我会听取您的建议并尝试拆分查询。我让你知道情况如何。谢谢 【参考方案1】:

感谢所有对此进行调查的人。 按照@nburk 的建议,我通过拆分我的查询来让它工作。 我能够通过创建自己的高阶组件来保持它的模块化。 如果有人有兴趣:

const Subscriber = (document, config) =>   

  return (WrappedComponent) =>  

    return class extends Component 

      constructor(props) 
        super(props)
        this.state=
        this.subscription = null
      
        componentWillReceiveProps(nextProps) 
          console.log(nextProps)
          if (!this.subscription && !nextProps.data.loading) 
            console.log("Sucess")
            let  subscribeToMore  = this.props.data
            this.subscription = [subscribeToMore(
            
              document: document,
              updateQuery: (previousResult,  subscriptionData ) => 
                console.log(subscriptionData)
                var newResult = [subscriptionData.data[config.modelName].node].concat(previousResult[config.propName])
                console.log(newResult)
                return  
                  //"allItems"
                  [config.propName]: newResult,
                

              ,
              onError: (err) => console.error(err),
            
              )]
                this.setState();
              
            


      render () 

        if (this.props.data.loading) 
          return (<div>Loading</div>)
        
           return (
                  <WrappedComponent ...this.props />
                 )

      
    
  


export default Subscriber

/*prop config = 
  propName: "string", //allItems // from query 
  //so I do not have to parse the gql query (would have to recieve from parent)
  modelName: "string" //Item 
  // from subscribe //so I do not have to parse the gql subscribe

*/

我现在像这样包装我的组件:

export const LocationList = graphql(gql`..., 
  options: (ownProps)=>(
    variables: 
      site: ownProps.site
    ))(
  Subscriber(gql`..., 
    propName:"allLocations",
    modelName:"Location",
  )(EntityList))

谢谢

【讨论】:

以上是关于为啥订阅完成后我的数据会消失?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在取消 git 提交后我的更改消失了,我该如何恢复它们?

为啥缩放训练和测试数据后我的 SVM 的性能会下降?

为啥聚合/裁剪后我的光栅文件大小会增加?

为啥每次单元测试后我的数据库都没有被清除?

为啥当我将 Meteor 应用程序转换为使用 Docker 时,我的 MongoDB 数据会消失?

为啥添加单个实体后我的核心数据需要很长时间才能保存?