2016-04-18 3 views
4

Я начинаю работу с Relay и стараюсь правильно работать с маршрутизацией. К сожалению, мне не очень повезло.Как правильно настроить реле и реакцию маршрутизации?

Здесь ошибка я получаю:

Uncaught TypeError: Component.getFragment is not a function

Вот код, у меня есть для справки:

index.jsx

import React from 'react'; 
import ReactDOM from 'react-dom'; 
import Relay from 'react-relay'; 
import {Router, Route, IndexRoute, browserHistory} from 'react-router'; 
import {RelayRouter} from 'react-router-relay'; 

import App from './modules/app'; 
import Home from './modules/home'; 

const AppQueries = { 
    store: (Component) => Relay.QL `query { 
    store { 
     ${Component.getFragment('store')} 
    } 
    }` 
}; 

ReactDOM.render(
    <RelayRouter history={browserHistory}> 
    <Route path='/' component={App} queries={AppQueries}> 
     <IndexRoute component={Home}/> 
    </Route> 
    </RelayRouter>, 
document.getElementById('ch-root')); 

app.jsx

import React, {Component} from 'react'; 
import Relay from 'react-relay'; 
import Header from './ui/header'; 
import Footer from './ui/footer'; 

class App extends Component { 
    render() { 
    return (
     <div id="ch-container"> 
     <Header/> 
     <section id="ch-body"> 
      {this.props.children} 
     </section> 
     <Footer/> 
     </div> 
    ); 
    } 
} 

App = Relay.createContainer(App, { 
    fragments: { 
    store: (Component) => Relay.QL ` 
     fragment on Store { 
     ${Component.getFragment('store')} 
     } 
    ` 
    } 
}); 

export default App; 

home.jsx

import React, {Component} from 'react'; 
import Relay from 'react-relay'; 
import Loader from './ui/loader'; 
import AccountSelector from './account/account-selector'; 

const APP_HOST = window.CH_APP_HOST; 
const CURR_HOST = `${window.location.protocol}//${window.location.host}`; 

class Home extends Component { 
    state = { 
    activeAccount: null, 
    loading: true 
    } 

    render() { 
    const {activeAccount, loading} = this.state; 

    if (loading) { 
     return <Loader/>; 
    } 

    if (!activeAccount && !loading) { 
     return <AccountSelector/>; 
    } 

    return (
     <h1>Hello!</h1> 
    ); 
    } 
} 

Home = Relay.createContainer(Home, { 
    fragments: { 
    store:() => Relay.QL ` 
     fragment on Store { 
     accounts { 
      unique_id, 
      subdomain 
     } 
     } 
    ` 
    } 
}); 

export default Home; 

UPDATE

Я сделал несколько изменений, предложенных freiksenet, как показано ниже. Но возникают следующие два вопроса:

  1. Что произойдет, когда я изменить маршрут и компонент, кроме Home визуализируется с помощью App компонента?
  2. теперь я получаю эту ошибку:

Warning: RelayContainer: Expected prop store to be supplied to Home , but got undefined . Pass an explicit null if this is intentional.

Вот изменения:

index.jsx

const AppQueries = { 
    store:() => Relay.QL `query { 
    store 
    }` 
}; 

app.jsx

import Home from "./home"; 

... 

App = Relay.createContainer(App, { 
    fragments: { 
    store:() => Relay.QL ` 
     fragment on Store { 
     ${Home.getFragment('store')} 
     } 
    ` 
    } 
}); 
+0

Ошибка означает, что она не знает, что такое «Компонент». Вам придется импортировать его так же, как вы импортировали 'App' и' Home'. Я предполагаю, что ошибка генерируется в файле 'index'? – Chris

+0

@Moon Response to your UPDATE 1: Вопрос 2: Вы не передали ни одного запроса для компонента «Главная». В файле index.jsx измените '' на ' queries = {AppQueries}'. Вопрос 1: Как уже упоминалось @freiksenet, 'App' не обязательно должен быть контейнером. Другим компонентам, предоставленным 'App', просто необходимо определить необходимые фрагменты. –

ответ

4

Определения фрагментов фактически не получают компоненты как аргументы, а представляют собой карту переменных контейнера, вам нужно использовать их только для условных фрагментов на основе значений переменных.

Запросы реле-маршрута не принимают никаких аргументов.

Вот изменения, которые вам нужно внести.

Запросы маршрутов в ретрансляции просто необходимо указать корневой запрос, который вы собираетесь получить на этом маршруте, без фрагмента.

index.jsx

const AppQueries = { 
    store:() => Relay.QL `query { 
    store 
    }` 
}; 

Ваш компонент App фактически не использует какие-либо данные реле, так что вы можете просто экспортировать нормальный компонент вместо контейнера.

export default class App extends Component { 

Если вам нужно передать некоторые данные реле к нему, вы не должны включать в себя дочерние фрагменты, потому что включение фрагментов только необходимы, когда вы непосредственно оказывают другие контейнеры, как прямые детей (а не как это. props.children).

Затем в Router вам нужно переместить запросы в Home.

ReactDOM.render(
    <RelayRouter history={browserHistory}> 
    <Route path='/' component={App}> 
     <IndexRoute component={Home} queries={AppQueries} /> 
    </Route> 
    </RelayRouter>, 
document.getElementById('ch-root')); 
+0

Большое спасибо за ответ. Я обновил свой код, как было предложено, а затем обновил свой вопрос новыми наблюдениями. – Moon

+0

@ Moon Aha. Кажется, я неправильно понял, что вы пытаетесь сделать немного. Исправлено сейчас. – freiksenet

Смежные вопросы