Relay: createContainer is not a function error

Created on 4 Aug 2017  路  9Comments  路  Source: facebook/relay

Hello,
I have a very basic react relay application and I am just learning this. A parent Component Main and a child component Links.

import React from "react";
import Relay from "react-relay";

class Link extends React.Component {
render() {
    let {link} = this.props;

    return(
        <li>
            <a href={link.url}>{link.title}</a>
        </li>
    );
}
}


Link = Relay.createContainer(Link,{  **//this is where the error happens**
fragments :{
    link:() => Relay.QL`fragment on Link {
        url,
        title,
    }`
}

});

export default Link;

The Main Relay container references the Link container

var React = require("react");
import Relay from "react-relay";
import Link from "./Link";

export default class Main extends React.Component {

static propTypes = {
    limit: React.PropTypes.number
}

static defaultProps = {
    limit : 5
}


render(){

    let content = this.props.store.links.slice(0,this.props.limit).map(
        link => {
            return <Link key={link._id} link={link}/>;

        }
    );
    return(<div>
            <h3>Links</h3>
            <ul>
                {content}
            </ul>
            </div>);
}
}

Main = Relay.createContainer(Main,{
fragments : {
    store : () => RELAY.QL`
    fragment on Store {
        links {
        _id,
        ${Link.getFragment('link')}
        }
    }
    `
}
});

However I get a Uncaught TypeError: _reactRelay2.default.createContainer is not a function

Any idea why this is happening?

I looked at the Relay documentation, and I seem to be using it correctly.

Most helpful comment

import Relay from "react-relay/classic"; if you are using the latest version of react-relay

All 9 comments

import Relay from "react-relay/classic"; if you are using the latest version of react-relay

Thanks, gone past that onto another error:

RelayRenderer.js?fe80:128 Uncaught Error: Invalid prop Container supplied to RelayRenderer, expected a RelayContainer.
at Object.Container (RelayPropTypes.js?f4b7:22)
at RelayRenderer._validateProps (RelayRenderer.js?fe80:126)
at RelayRenderer.componentDidMount (RelayRenderer.js?fe80:116)
at eval (ReactCompositeComponent.js?063f:264)
at measureLifeCyclePerf (ReactCompositeComponent.js?063f:75)
at eval (ReactCompositeComponent.js?063f:263)
at CallbackQueue.notifyAll (CallbackQueue.js?7abf:76)
at ReactReconcileTransaction.close (ReactReconcileTransaction.js?2d36:80)
at ReactReconcileTransaction.closeAll (Transaction.js?91bc:209)
at ReactReconcileTransaction.perform (Transaction.js?91bc:156)

Getting the below warnings before that

Warning: Failed prop type: Invalid prop Container supplied to RelayRenderer, expected a RelayContainer.
in RelayRenderer (created by RelayRootContainer)
in RelayRootContainer

I am using the Relay.RootContainer to render the Main (which is the parent) Component in app.js

var React = require("react");
var ReactDOM = require("react-dom");
import Main from "./components/Main";
import Relay from "react-relay/classic";

class HomeRoute extends Relay.Route{
static routeName = 'Home';
static queries = {
    store: (Component) => Relay.QL`
        query MainQuery {
            store { ${Component.getFragment('store')}}
        }
    `
}
}

ReactDOM.render(<Relay.RootContainer 
            Component={Main}
            route={ new HomeRoute()}
        />,
        document.getElementById('react'));

Should I be using the Relay.RelayRootContainer or the Relay.RelayContainer to indicate the Root Container in relay?

try to use relay modern instead

try this example here https://github.com/sibelius/ReactNavigationRelayModern

or the classic version here https://github.com/sibelius/ReactNavigationRelayModern/tree/relay-classic

@sibelius This is really the only answer here. OP if you are just learning this you should be focusing on Relay Modern.

https://facebook.github.io/relay/docs/relay-modern.html

https://www.howtographql.com/react-relay/0-introduction/

@scotmatson @sibelius Follow up questions for you.
I have a large complicated json docs stored in MongoDB- which is my DB for the application. With relay-modern, what is the best way to get started?

  • Should I manually create the graphql.schema, taking care to adhere to relay-moderns limitations? Then I can run the relay-compiler on this schema and generate those js files. Should I do this on all the fields, or just the ones I am interested in?

  • Should I just model the graphql.schema according to the full json document? That way, I think I might be able to just do a find({}) in the resolve portion and get the fields I want. This will make it easier to get more fields to display. Else, should I model the graphql.schema according to the fields I am interested in?

  • Should I create the schema.js file first (relay classic method), and then do introspection on it to generate the schema.json? - this is the relay classic way. Is it still applicable in relay modern?

Really need your guidance in going forward with this.

Thanks!

@sibelius I didn't understand. What is a boilerplate? My starting point is a json structure stored in MongoDB. How do I get the schema from that?

@sibelius Apologise for being a bit hasty before. From what I can understand, the create-graphql builds prod ready graphql servers and adds mutations, types etc to the project. This us built on the boilerplate code that you pointed me to... But I didn't really understand the "Story" example. Would it be possible for you to explain this to me a bit better? Again, just getting started.

I'm closing this issue since the original question was answered. Please feel free to continue discussion here.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

amccloud picture amccloud  路  3Comments

piotrblasiak picture piotrblasiak  路  3Comments

jstejada picture jstejada  路  3Comments

derekdowling picture derekdowling  路  3Comments

mike-marcacci picture mike-marcacci  路  3Comments