How to configure Relay and React Routing?

I start with Relay and try to make my routing work properly. Unfortunately, I was not very lucky.

Here is the error I get:

Uncaught TypeError: Component.getFragment is not a function

Here is the code I have for your reference:

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

I made a few changes freiksenetas suggested below. But this raises the following two questions:

  • What happens when I change the route and a component other than Homewill be displayed by the component App?
  • Now I get this error:

Warning: RelayContainer: Expected support storefor delivery Home, but received undefined. Pass explicit null, if intentional.

Here are the changes:

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')}
      }
     `
  }
});
+4
1

, , , .

Relay Route .

, .

Relay , , .

index.jsx

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

, .

export default class App extends Component {

Relay, , , ( this.props.children).

Router Home.

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

All Articles