2017-07-21 28 views
9

पर पास नहीं किया गया है मुझे रिले मॉडर्न में रीफ्रैचकंटनर स्थापित करने में कुछ समस्याएं आ रही हैं। एक मूल घटक QueryRenderer है, जो प्रारंभिक क्वेरी चलाता है, जो बच्चे के घटक के प्रोप को उचित रूप से पॉप्युलेट करता है (एक-प्रोप-दंगे? एह? एह ?!)। RefetchContainer हमारे सभी चर निर्दिष्ट करता है, और एक इनपुट फ़ील्ड के ऑन चेंज इवेंट पर, नए चर के साथ एक क्वेरी को फिर से चलाता है। यह सब पूरी तरह से काम करता है, सिवाय इसके कि बच्चे के प्रोप को प्राप्त नए डेटा के साथ कभी अपडेट नहीं किया जाता है। मैं रिले स्टोर को ड्रिल कर सकता हूं और देख सकता हूं कि वास्तव में उचित डेटा के साथ क्वेरी प्राप्त हुई थी। थोड़ी देर के लिए इसके खिलाफ मेरा सिर बन गया और मैं कुछ मदद की सराहना करता हूं। शायद कुछ आसान मैं याद कर रहा हूँ। और भगवान रिले आधुनिक दस्तावेज जानता है स्पैस है।रिले मॉडर्न रिफैचकंटनर प्रोप को घटक

मैंने चारों ओर पोक किया है और उचित समाधान नहीं मिल रहा है।

import React, { Component } from 'react'; 
import { connect } from 'react-redux'; 
import PropTypes from 'prop-types'; 
import { graphql, QueryRenderer } from 'react-relay'; 
import Search from './Search'; 

const propTypes = { 
    auth: PropTypes.object.isRequired, 
}; 

class SearchContainer extends Component { 
    render() { 
    return (
     <QueryRenderer 
     query={graphql` 
      query SearchContainerQuery($search: String!){ 
      users: searchUsers(search:$search, first:10){ 
       ...Search_users 
      } 
      }`} 
     variables={{ search: 'someDefaultSearch' }} 
     environment={this.props.auth.environment} 
     render={({ error, props }) => { 
      if (error) { 
      console.log(error); 
      } 
      if (props) { 
      return <Search users={props.users} />; 
      } 
      return <div>No Dice</div>; 
     }} 
     /> 
    ); 
    } 
} 

SearchContainer.propTypes = propTypes; 

export default connect(state => ({ auth: state.auth }))(SearchContainer); 

createRefetchContainer के साथ बच्चे घटक: relay refetch doesn't show the result

QueryRenderer साथ माता पिता घटक: यह आदमी एक समान समस्या हो रही किया जा रहा है

import React, { Component } from 'react'; 
import PropTypes from 'prop-types'; 
import { createRefetchContainer, graphql } from 'react-relay'; 

const propTypes = { 
    relay: PropTypes.object.isRequired, 
    users: PropTypes.object, 
}; 

const defaultProps = { 
    users: {}, 
}; 

class Search extends Component { 
    render() { 
    return (
     <div> 
     <input 
      type="text" 
      onChange={(e) => { 
      e.preventDefault(); 
      this.props.relay.refetch({ 
       search: e.target.value, 
      }); 
      }} 
     /> 
     <ul> 
      {this.props.users.nodes.map(user => 
      <li key={user.id}>{user.username}</li>, 
     )} 
     </ul> 
     </div> 
    ); 
    } 
} 

Search.propTypes = propTypes; 
Search.defaultProps = defaultProps; 

export default createRefetchContainer(
    Search, 
    { 
    users: graphql.experimental` 
     fragment Search_users on SearchUsersConnection 
     @argumentDefinitions(
     search: {type: "String", defaultValue: ""} 
    ) { 
     nodes { 
      id 
      displayName 
      username 
      } 
     } 
    `, 
    }, 
    graphql.experimental` 
    query SearchRefetchQuery($search: String!) { 
     users: searchUsers(search:$search, first:10){ 
     ...Search_users @arguments(search: $search) 
     } 
    } 
    `, 
); 

GraphQL इस तरह दिखता है:

# A connection to a list of `User` values. 
type SearchUsersConnection { 
    # Information to aid in pagination. 
    pageInfo: PageInfo! 

    # The count of *all* `User` you could get from the connection. 
    totalCount: Int 

    # A list of edges which contains the `User` and cursor to aid in pagination. 
    edges: [SearchUsersEdge] 

    # A list of `User` objects. 
    nodes: [User] 
} 

नेटवर्क सी सभी उचित रूप से बनाए जाते हैं, और डेटा अपेक्षित के रूप में वापस कर दिया जाता है। NetworkCalls

ऐसा लगता है @arguments निर्देश को फिर से लाएं क्वेरी यहाँ से बाहर छोड़ा जा सकता है:

query SearchRefetchQuery($search: String!) { 
     users: searchUsers(search:$search, first:10){ 
      ...Search_users @arguments(search: $search) 
     } 
} 

(हटाने के लिए यह कोई प्रभाव नहीं लगता है)

मैं @arguments जोड़ने की कोशिश की है यहां अनुशंसा के अनुसार मूल घटक के टुकड़े के लिए निर्देश: Pass variables to fragment container in relay modern, कोई प्रभाव नहीं।

+0

खेद में बहुत मदद नहीं है .. fwiw मैंने पूरी तरह से QuireRenderer को नए प्रोप पास करने के लिए रीफ्रैचकंटर्स को छोड़ दिया है जो काम पूरा हो जाता है। उदाहरण: https://github.com/NCI-GDC/portal-ui/blob/next/src/packages/@ncigdc/modern_components/GenesTable/GenesTable.relay.js – azium

+1

@azium Yep, ऐसा लगता है कि यह ठीक काम करता है। यह सिर्फ मुझे परेशान करता है कि रीफैचकंटनर, विशेष रूप से इसके लिए डिज़ाइन किया गया है, सेट अप करना बहुत मुश्किल है! – cntrlz

+0

मेरे पास एक ही समस्या है और मैं दीवार पर अपने सिर को टक्कर लगी हूं :( –

उत्तर

3

ओह मुझे लगता है कि मुझे एक ही समस्या से गुजरना पड़ा। अगर मुझे सही ढंग से याद है तो मेरा मानना ​​है कि "आईडी" रिले प्रोप को पास करने के लिए घटक की पहचान करने के लिए उपयोग कर रहा है, प्रारंभिक क्वेरी के चर शामिल है, इसलिए क्वेरीरेंडर की क्वेरी से अपने कंटेनर खंड को अनचाहे करने का प्रयास करें।

सेटअप है कि मेरे लिए काम किया निम्नलिखित की तरह कुछ है:

<QueryRenderer 
    variables={{search: 'someDefaultSearch', count: 10}} 
    query={graphql` 
    query SearchContainerQuery($search: String!, $count: Int!){ 
     # if we want defaults we need to "prepare" them from here 
     ...Search_users @arguments(search: $search, count: $count) 
    } 
    `} 
    environment={this.props.auth.environment} 
    render={({ error, props: relayProps }) => { 
    // I use relayProps to avoid possible naming conflicts 
    if (error) { 
     console.log(error); 
    } 
    if (relayProps) { 
     // the users props is "masked" from the root that's why we pass it as is 
     return <Search users={relayProps} />; 
    } 
    return <div>No Dice</div>; 
    }} 
/> 

और refetchContainer कुछ ऐसा दिखाई देगा:

export default createRefetchContainer(
    Search, 
    { 
    users: graphql` 
     # In my schema the root is called RootQueryType 
     fragment Search_users on RootQueryType 
     @argumentDefinitions(
     search: {type: "String"} 
     count: {type: "Int!"} 
    ) { 
     searchUsers(search: $search, first: $count) { 
      nodes { 
      id 
      displayName 
      username 
      } 
     } 
     } 
    ` 
    }, 
    graphql` 
    query SearchRefetchQuery($search: String!, $count: Int!) { 
     ...Search_users @arguments(search: $search, count: $count) 
    } 
    ` 
); 

ध्यान दें कि उपरोक्त उदाहरण मानता है रिले v1.3 जहां graphql.experimental पदावनत किया गया है। साथ ही, मुझे याद नहीं है कि @arguments चाल के साथ searchUsers कार्य को अलियासिंग करने का अपना दृष्टिकोण बनाना संभव है।

मेरा आखिरी सुझाव आपके डीबगर को चालू कर रहा है और देखता है कि डेटा प्राप्त होने पर क्या चल रहा है।

अंत में, आपकी टिप्पणियों के अनुसार, मैं मानता हूं कि यह एक बग हो सकता है। चलो देखते हैं कि आपके द्वारा रिपोर्ट की गई समस्या में चीजें कैसे विकसित होती हैं।

2

जैसा कि अन्य उत्तरों में बताया गया है, यह वास्तव में व्यवहार की उम्मीद है, और मैं थोड़ा जवाब देने का प्रयास करूंगा।

जब रीफ्रैक कहा जाता है और refetchQuery निष्पादित किया जाता है, तो रिले वास्तव में घटक को फिर से प्रस्तुत करने के लिए क्वेरी के परिणाम का उपयोग नहीं करता है। यह सब स्टोर में पेलोड सामान्य है और किसी प्रासंगिक सदस्यता को आग लगाना है। इसका अर्थ यह है कि यदि प्राप्त डेटा उस डेटा से असंबंधित है जो घुड़सवार कंटेनर की सदस्यता लेता है (उदाहरण के लिए एक पूरी तरह से अलग नोड आईडी का उपयोग करना जिसमें कोई डेटा ओवरलैप नहीं है), तो घटक फिर से प्रस्तुत नहीं करेगा।

इस विशिष्ट परिदृश्य में, कंटेनर फिर से प्रस्तुत नहीं करने का कारण है, यानी refetchQuery द्वारा निकाले गए परिवर्तनों की सदस्यता क्यों नहीं ली गई है, यह सदस्यता के आधार पर कैसे है। एक सदस्यता मूल रूप से snapshot की सदस्यता है, जो मूल रूप से एक ठोस खंड और उस समय से जुड़े डेटा और रिकॉर्ड को दर्शाती है - जब स्नैपशॉट परिवर्तन से जुड़े रिकॉर्ड, उस स्नैपशॉट के लिए सदस्यता अधिसूचित की जाएगी परिवर्तन।

इस मामले में, यह देखते हुए कि कंटेनर के लिए टुकड़े में कोई चर नहीं है, स्नैपशॉट जो इसे सब्सक्राइब करेगा, केवल प्रारंभिक नोड से जुड़ा होगा; रीफ्रैक होने के बाद और स्टोर अपडेट हो जाता है, नए नोड के लिए रिकॉर्ड अपडेट कर दिए जाएंगे, लेकिन उस मूल स्नैपशॉट से जुड़े रिकॉर्ड में बदलाव नहीं आया है, इसलिए इसके लिए सब्सक्राइबर को अधिसूचित नहीं किया जाएगा।

इसका मतलब है कि रीफ्रैच कंटेनर का उपयोग वास्तव में तब किया जाना चाहिए जब आप घटक खंड में चर बदल रहे हों। यहां प्रदान किए गए समाधान वैध हैं, यानी रीफ्रैच कंटेनर के लिए खंड में चर शामिल हैं या QueryRenderer में एक स्तर को नए चर सेट करना शामिल है।

यह दस्तावेज़ों में निश्चित रूप से अधिक स्पष्ट किया जा सकता है, इसलिए मैं इसे प्रतिबिंबित करने के लिए उन्हें अपडेट कर दूंगा। आशा है कि ये आपकी मदद करेगा!

संबंधित मुद्दे