2017-07-21 29 views
9

Relay Modern'de bir refetchContainer ayarlayarak bazı sorunlar yaşıyorum. Bir ana bileşen, bir alt sorguyu çalıştıran ve alt öğe bileşeninin uygun şekilde oluşturduğu QueryRenderer'dır (a-prop-riately? Eh? Eh ?!). RefetchContainer tüm değişkenlerimizi belirtir ve bir giriş alanının onChange olayı üzerinde yeni değişkenlerle bir sorguyu yeniden çalıştırır. Tüm bunlar mükemmel çalışır, ancak çocuğun sahne alanı yeni alınan verilerle asla güncellenmez. Relay mağazasını açabilir ve sorgunun gerçekten uygun verilerle alındığını görebilirim. Bir süredir başımı çarptım ve biraz yardımın için minnettarım. Muhtemelen basit bir şey eksik. Ve Lord Relay'i biliyor Modern dokümantasyon seyrek.Relay Modern RefetchContainer öğeleri, bileşene aktarılmadı

Etrafımda dolandım ve uygun bir çözüm bulamıyorum. createRefetchContainer ile

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

çocuk bileşeni: QueryRenderer ile relay refetch doesn't show the result

ebeveyn bileşeni: Bu adam benzer bir sorun yaşıyor gibi görünüyor

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 şuna benzer:

# 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] 
} 

Ağ c alls uygun şekilde yapılır ve veri beklendiği gibi döndürülür. NetworkCalls

Bu @arguments direktif burada tekrar getirin sorgunun dışında bırakılabilir görünüyor:

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

Ben @arguments ekleyerek denedim

(hiçbir etkiye sahip görünmektedir kaldırma) Buradaki tavsiyelere göre ana bileşenin parçasına ilişkin direktif: Pass variables to fragment container in relay modern, hiçbir etkisi yoktur.

+0

Üzgünüm fazla yardım .. fwiw RefetchContainers'ı, işi tamamlayan QueryRenderer'a yeni sahne almak için tamamen reddediyorum. örnek: https://github.com/NCI-GDC/portal-ui/blob/next/src/packages/@ncigdc/modern_components/GenesTable/GenesTable.relay.js – azium

+1

@azium Evet, bu iyi çalışıyor gibi görünüyor. Sadece, özellikle bunun için tasarlanan refetchContainer'ın kurulumu çok zor olduğu beni rahatsız ediyor! – cntrlz

+0

Ben tam olarak aynı sorunu yaşıyorum ve ben kafamı duvarda becermeye başladım :( –

cevap

3

Sanırım benzer bir problem yaşadım. Doğru hatırlamıyorsam, "id" Relay'in props'leri geçecek bileşeni tanımlamak için kullandığını, ilk sorgu için değişkenleri içerdiğini ve böylece QueryRenderer sorgusundan konteyner parçanızı kaldırmayı deneyeceğine inanıyorum.

benim için çalıştı kurulum aşağıdaki gibi bir şey: Yukarıdaki örnekte Röle v1.3 nerede graphql.experimental varsayar

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

Uyarı:

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

Ve refetchContainer gibi bir şey olur kullanımdan kaldırıldı. Ayrıca, @arguments hile ile searchUsers çalışmasının taklit etme yaklaşımını yapmanın mümkün olduğunu hatırlamıyorum.

Son önerim, hata ayıklayıcınızı açıyor ve verileri aldığınızda neler olduğunu görüyor.

Son olarak, yorumlarınıza göre, bunun bir HATA olabileceğini kabul ediyorum. Bildirdiğiniz konuda işlerin nasıl geliştiğini görelim.

2

Diğer cevaplarda da belirtildiği gibi, bu aslında beklenen bir davranıştır ve cevabın biraz üzerinde genişlemeye çalışacağım.

Refetch çağrıldığında ve refetchQuery yürütüldüğünde, Relay aslında bileşenin yeniden oluşturulması için sorgunun sonucunu kullanmaz. Tek yaptığı, yükü depoya normalize etmek ve ilgili abonelikleri ateşlemek. Bu, eğer getirilen veri, monte edilmiş konteynerin abone olduğu verilere bağlı değilse (örneğin, herhangi bir veriyi örtmeyen tamamen farklı bir düğüm kimliği kullanılarak), o zaman bileşenin yeniden oluşturmayacağı anlamına gelir.

Bu özel senaryoda, kapsayıcının neden yeniden oluşturulmadığı, yani neden refetchQuery tarafından yapılan değişikliklere abone olmadığının nedeni, aboneliklerin nasıl ayarlandığıdır. Abonelik, temel olarak somut bir parçayı temsil eden snapshot numaralı aboneliğe ait bir aboneliktir. Anlık görüntü değişikliği ile ilişkili kayıtlar, söz konusu anlık görüntü için abonelik bildirilir. değişir. Bu örnekte, kap için olan parçanın değişken olmadığı göz önüne alındığında, abone olunacağı anlık görüntü yalnızca ilk düğümle ilişkilendirilecektir; refetch gerçekleştikten ve mağaza güncellendikten sonra, yeni düğümün kayıtları güncellendi, ancak o orijinal anlık görüntüsüyle ilişkili kayıt değişmedi, bu yüzden ona abone olan konteyner bildirilmeyecek.

Bu, Refetch kapsayıcılarının yalnızca bileşen parçasındaki değişkenleri değiştirdiğinizde kullanılması gerektiği anlamına gelir. Burada sağlanan çözümler geçerlidir, yani refetch konteynerindeki parçadaki değişkenler dahil veya QueryRenderer'da bir seviye yukarı yeni değişkenler belirlenir.

Bu, dokümanlarda kesinlikle daha net bir şekilde gösterilebilir, dolayısıyla bunları yansıtacak şekilde güncelleyeceğim. Umarım bu yardımcı olur!

İlgili konular