2017-04-11 37 views
-1

爲什麼在訂閱過程中數據未定義? 我想弄清楚我的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> 
    ) 
    } 
} 
+1

請確保代碼格式正確!在調用'graphql'前調用'gql'調用單獨的變量,然後在調用中引用這些變量以提高可讀性是個好主意。另外,請提供更多有關確切錯誤信息的信息,否則將很難提供幫助。 – nburk

+0

謝謝,我實際上沒有收到任何錯誤消息。當我將訂閱功能添加到道具中時,注入的數據道具消失了,因此我將它添加到我自己的數據對象中,並注入了數據:props.data。但是現在當我訂閱時,我從數據中刪除了allLocations屬性。也許我誤解了什麼更新查詢返回,因爲我認爲它會爲我提供一個數據對象。 –

+0

另外,我已經能夠通過在下面的組件中調用我的訂閱查詢來獲得訂閱,但我認爲這樣可以使我的代碼更少重複使用,因爲我將對多個數據模型多次重複此過程。我會接受你的建議並嘗試分解查詢。我讓你知道它是怎麼回事。謝謝 –

回答

0

感謝所有誰看着這一點。 我通過按照@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)) 

感謝

相關問題