2017-04-11 9 views
-1

サブスクリプションが完了したときにデータが未定義になるのはなぜですか? 私のprops.data.allLocationsがどこから来ているのかわかりません。どんな助けもありがとう。このに見えたすべての人へサブスクリプションが完了するとデータが消えるのはなぜですか?

//高次の成分を

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

コードが正しくフォーマットされていることを確認してください。

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 } */ 

私は今、このように私のコンポーネントを包みます! 'graphql'を呼び出す前に、' gql'の呼び出し結果を別々の変数に引き出し、呼び出し時にこれらの変数のみを参照して読みやすくするのは良い考えです。また、正確なエラーメッセージに関する情報をもう少し提供してください。そうしないと、手助けが困難になります。 – nburk

+0

ありがとうございます、実際にはエラーメッセージが表示されません。サブスクリプション関数を小道具に追加すると、注入されたデータの小道具が消えたので、私はそれを自分自身にデータオブジェクトを挿入するデータに追加します:props.data。しかし今私が購読すると、私はデータからallLocationsプロパティを失います。たぶん、私はデータオブジェクトを私に渡すと仮定して、私は更新クエリが返すものを誤解しています。 –

+0

また、下位コンポーネントでサブスクリプションクエリを呼び出すことでサブスクリプションを取得できましたが、多くのデータモデルでこのプロセスを複数回繰り返すため、コードの再利用性を低くすると考えました。私はあなたのアドバイスを受けて、クエリを分割しようとします。私はそれがどのように進むのかを知らせます。ありがとう –

答えて

0

感謝。 @nburkが提案したように私のクエリを分割して動作させました。 独自の高次コンポーネントを作成することで、モジュール化した状態に保つことができました。 誰もが興味を持っている場合:

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

おかげ

関連する問題