Giter Club home page Giter Club logo

meteor-react-layout's Introduction

NOTE

With Meteor 1.3, use react-mounter instead of this.
Read this article for more information: Getting Started with Meteor 1.3 and React.

React Layout

Simple React Layout Manager for Meteor with SSR Support.

With React Layout you can easily render react components both alike in client and server. In the server it uses Flow Router's upcoming SSR apis.

Adding it to your project

meteor add kadira:react-layout

Then you use ReactLayout.render() to render your component. Rather than simply rendering a component, you can also use it as a layout manager like Flow Layout.

Let's see few ways we can use the React Layout

Rendering a Simple Component

Let's say we've a pretty simple component like this:

WelcomeComponent = React.createClass({
  render() {
    return <div>
      <h1>Hello, {this.props.name}</h1>
    </div>
  }
});

Now we can render this component with:

ReactLayout.render(WelcomeComponent)

Note that, here you don't create an element, but simply use the component class.

You can also pass props like this:

ReactLayout.render(WelcomeComponent, {name: "Arunoda"})

Using as a Layout Manager

We can simply use ReactLayout as a simple layout manager. Let's say we've a layout called MainLayout.

MainLayout = React.createClass({
  render() {
    return <div>
      <header>
        This is our header
      </header>
      <main>
        {this.props.content}
      </main>
      <footer>
        This is our footer
      </footer>
    </div>
  }
});

Now let's try render our WelcomeComponent into the MainLayout.

ReactLayout.render(MainLayout, {
  content: <WelcomeComponent name="Arunoda" />
})

That's it.

Using inside Flow Router

React Layout works pretty nicely with Flow Router. Here's an example:

FlowRouter.route("/", {
  subscriptions: function() {
    var selector = {category: {$ne: "private"}};
    this.register('posts', Meteor.subscribe('posts', selector));
  },
  action: function() {
    ReactLayout.render(BlogLayout, {
      content: <PostList />
    });
  }
});

FlowRouter.route('/post/:_id', {
  name: 'post',
  subscriptions: function(params) {
    this.register('singlePost', Meteor.subscribe('singlePost', params._id));
  },
  action: function(params) {
    ReactLayout.render(BlogLayout, {
      content: <PostPage _id={params._id} />
    });
  }
});

Add Custom Props to Root Element

Sometimes, you need to set classes and other props to the root elements. Then this is how to do it. Simply call following function before render anything:

ReactLayout.setRootProps({
  className: "ui middle aligned center aligned grid"
});

If you are using SSR, you need to call setRootProps in the server side.

Using React Context

If you'd like to use getChildContext() (for integrating Material-UI, for example), you must render the child component within the layout. You can do this by passing a function that renders the component rather than the component itself. In your layout component you can then call the function directly to render the component. See #2 for a full discussion.

MainLayout = React.createClass({

  childContextTypes: {
    muiTheme: React.PropTypes.object
  },

  getChildContext: function() {
    return {
      muiTheme: ThemeManager.getCurrentTheme()
    };
  },

  render() {
    return <div>
      <header>
        This is our header
      </header>
      <main>
        {this.props.content()}  /* note, this is a function call */
      </main>
      <footer>
        This is our footer
      </footer>
    </div>
  }
});

HomePage = React.createClass({
  render () {
    return (
      <div>
        <h1>This is the home page</h1>
        /* Rendering of material-ui components will work here */
      </div>
    );
  }
});

FlowRouter.route('/', {
  name: 'home',
  action: function(params) {
    /* The key 'content' is now a function */
    ReactLayout.render(MainLayout, {
      content() {
        return <HomePage />;
      }
    });
  }
});

SSR Support

SSR Support is still experimental and you need to use meteorhacks:flow-router-ssr for that. Have a look at this sample app.

meteor-react-layout's People

Contributors

arunoda avatar deanius avatar rajikaimal avatar sergiob avatar timfletcher avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

meteor-react-layout's Issues

Assign React props to FlowRouter

May I have some documentation on how to achieve this, please?

FlowRouter.route('/dashboard', {
  name: 'dashboard',
  action(){
    var x = Projects.find().fetch(); // this not working
    console.log(x); // x is []. Why?
    ReactLayout.render(App, {
      nav: <Nav />,
    content: <Profile data={x}/>
    });
  }
});

In my app I wish to say this.props.data but the array is empty. I have to put the logic into the react component. Is that the correct way? I hope not.

Where is a clean and understandable documentation with FR and React?

React layout and forms?

Hi,

I've been running into a small issue, and I have no idea what's going wrong and why.. This may be my fault for not using it right, but please correct me!

I have my Main layout:

Main = React.createClass({  
  render() {
    return <body>
        <div className="body-wrapper">
            <PersonalMenu />
            <div className="content-wrapper">
                <Header />
            {this.props.content}
            <GameForm />
            <Footer />
            </div>
        </div>
    </body>

  }
});

My GameForm is this

GameForm = React.createClass({
  handleSubmit: function(e) {
    e.preventDefault();
    var author = this.refs.author.value.trim();
    var text = this.refs.text.value.trim();
    if (!text || !author) {
      return;
    }
    console.log(author);
    console.log(text);
    // TODO: send request to the server
    this.refs.author.value = '';
    this.refs.text.value = '';
    return;
  },

  render: function() {
    return (
      <form className="commentForm" onSubmit={this.handleSubmit}>
        <input type="text" placeholder="Your name" ref="author" />
        <input type="text" placeholder="Say something..." ref="text" />
        <input type="submit" value="Post" />
      </form>
    );
  }
});

However, when I visit the page, the onSubmit is NOT working at all. The form just gets posted and the page refreshes.

When I change my Main to

Main = React.createClass({
  componentDidMount: function() {
    ReactDOM.render(<GameForm />, document.getElementById("render-target"));
  },

  render() {
    return <body>
        <div className="body-wrapper">
            <PersonalMenu />
            <div className="content-wrapper">
                <Header />
            {this.props.content}
            <div id="render-target"> </div>
            <Footer />
            </div>
        </div>
    </body>

  }
});

The onsubmit works when using the last Main layout. What's going wrong? Am I doing something wrong? Or what is supposed to happen?

Child component events getting eaten?

Hey...just wondering if I'm either doing something wrong, or there's a bug with ReactLayout.

I've got a set of components being used for a layout (per the 'layout manager' example in the documentation), and then some stuff being rendered inside it. The problem is...when a form (child component) is submitted, the event assigned to be fired off...doesn't ever get fired off.

If I render the component WITHOUT the <MainLayout /> component around it...it fires off as expected, but when it's rendered inside said component, events do not work.

I have relevant code in a gist, and the project is also in a repository on BitBucket...not sure if it's a misunderstanding on my end (it could be, I'm new to this React stuff) or with ReactLayout itself.

Gist: https://gist.github.com/czbaker/2101526219eea5330553
Repository: https://bitbucket.org/czbaker/karuto

can I get the HTML when I call ReactLayout.render?

hello everyone,

I'm tring to render react components in the server side in order to use it for generating PDF document from the HTML, but I can't figure out a way to get the rendred HTML.
is there anyway to get the HTML from ReactLayout.render() ?

Warning: ReactMount: Root element ID differed from reactRootID.

I'm getting a whole bunch of errors when switching from one page to another.

I'm getting this

Warning: ReactMount: Root element ID differed from reactRootID.warning @ warning.js:45ReactMount.findReactContainerForID @ ReactMount.js:651isValid @ ReactMount.js:199getNode @ ReactMount.js:161trapBubbledEventsLocal @ ReactDOMComponent.js:269assign.notifyAll @ CallbackQueue.js:65ON_DOM_READY_QUEUEING.close @ ReactReconcileTransaction:81Mixin.closeAll @ Transaction.js:202Mixin.perform @ Transaction.js:149batchedMountComponentIntoNode @ ReactMount.js:282Mixin.perform @ Transaction.js:136ReactDefaultBatchingStrategy.batchedUpdates @ ReactDefaultBatchingStrategy:62batchedUpdates @ ReactUpdates.js:94ReactMount._renderNewRootComponent @ ReactMount.js:476wrapper @ ReactPerf.js:66ReactMount._renderSubtreeIntoContainer @ ReactMount.js:550ReactMount.render @ ReactMount.js:570wrapper @ ReactPerf.js:66(anonymous function) @ react_layout.js:69ReactLayout._ready @ react_layout.js:76ReactLayout._renderClient @ react_layout.js:66ReactLayout.render @ react_layout.js:44FlowRouter.route.action @ router.jsx:3Route.callAction @ route.js:51(anonymous function) @ router.js:447Tracker.nonreactive @ tracker.js:589(anonymous function) @ router.js:431Tracker.Computation._compute @ tracker.js:323Tracker.Computation._recompute @ tracker.js:342Tracker._runFlush @ tracker.js:481Tracker.flush @ tracker.js:441Router._invalidateTracker @ router.js:489afterAllTriggersRan @ router.js:101Triggers.runTriggers @ triggers.js:89route._actionHandle @ router.js:105(anonymous function) @ client.browserify.js:570nextEnter @ client.browserify.js:402(anonymous function) @ client.browserify.js:571nextEnter @ client.browserify.js:402(anonymous function) @ client.browserify.js:571nextEnter @ client.browserify.js:402(anonymous function) @ client.browserify.js:571nextEnter @ client.browserify.js:402(anonymous function) @ client.browserify.js:571nextEnter @ client.browserify.js:402nextExit @ client.browserify.js:390(anonymous function) @ client.browserify.js:571nextExit @ client.browserify.js:391(anonymous function) @ client.browserify.js:571nextExit @ client.browserify.js:391(anonymous function) @ client.browserify.js:571nextExit @ client.browserify.js:391(anonymous function) @ client.browserify.js:571nextExit @ client.browserify.js:391(anonymous function) @ client.browserify.js:571nextExit @ client.browserify.js:391page.dispatch @ client.browserify.js:406page.show @ client.browserify.js:297self._page.(anonymous function) @ router.js:382onclick @ client.browserify.js:697
warning.js:45 Warning: ReactMount: Root element has been removed from its original container. New container: null

It does not crash my app, but getting 170+ errors per page switch seems unhealthy.. What am I doing wrong?

For reference, this is my routing

FlowRouter.route("/", {
  action: function() {
    ReactLayout.render(Main)
  }
});

how to add head / meta fields?

I want to add some custom fields so this will render properly on a mobile device.

eg like (jade)

head
  //- this is critical for mobile and emulation to look and work properly
  title SuperSite
  meta(name='viewport', content='width=device-width, maximum-scale=1, user-scalable=no')
  meta(http-equiv="X-UA-Compatible" content="IE=edge")
  meta(charset="utf-8")
  //- link(rel="shortcut icon" href="/assets/ico/favicon.png")

Using ES6 classes extending from React.Component doesn't work

Fairly new to React so apologies if this is a silly question. I was experimenting with this blog post as a way to streamline some of my JSX. I had a component based on React.createClass, but then changed it to this:

class Add extends React.Component {

newItem(event) {
event.preventDefault()
var titleNode = React.findDOMNode(this.refs.title)
var title = titleNode.value.trim()
Lists.findOne().$push({items: {_id: Random.id(), title: title, done: false}})
titleNode.value = ""
titleNode.focus()
}

render() {
return





Add

}

}

Now, nothing renders. I call it like so:

ReactLayout.render(Layout, {content:

, footer: })

What am I doing wrong?

Thanks.

Many compatibility issues

You guys currently have a lot of issues on the web and from my experience with different versions of react, and meteor not being compatible. Are you going to put out any solid instructions for moving forward or are you content to just leave users struggling to figure out how to fit your package in?

WARNING: npm peer requirements not installed:

i'm using meteor Meteor 1.4.1.1
i installed the packages but the console log return this

I20160915-17:19:19.749(2)? [Error: Can't find npm module 'react-addons-transition-group/package.json'. Did you forget to call 'Npm.depends' in package.js within the 'modules-runtime' package?]
I20160915-17:19:19.750(2)? [Error: Can't find npm module 'react-addons-css-transition-group/package.json'. Did you forget to call 'Npm.depends' in package.js within the 'modules-runtime' package?]
I20160915-17:19:19.751(2)? [Error: Can't find npm module 'react-addons-linked-state-mixin/package.json'. Did you forget to call 'Npm.depends' in package.js within the 'modules-runtime' package?]
I20160915-17:19:19.752(2)? [Error: Can't find npm module 'react-addons-create-fragment/package.json'. Did you forget to call 'Npm.depends' in package.js within the 'modules-runtime' package?]
I20160915-17:19:19.753(2)? [Error: Can't find npm module 'react-addons-update/package.json'. Did you forget to call 'Npm.depends' in package.js within the 'modules-runtime' package?]
I20160915-17:19:19.754(2)? [Error: Can't find npm module 'react-addons-pure-render-mixin/package.json'. Did you forget to call 'Npm.depends' in package.js within the 'modules-runtime' package?]
I20160915-17:19:19.754(2)? [Error: Can't find npm module 'react-addons-test-utils/package.json'. Did you forget to call 'Npm.depends' in package.js within the 'modules-runtime' package?]
I20160915-17:19:19.755(2)? [Error: Can't find npm module 'react-addons-perf/package.json'. Did you forget to call 'Npm.depends' in package.js within the 'modules-runtime' package?]
W20160915-17:19:19.756(2)? (STDERR) WARNING: npm peer requirements not installed:
W20160915-17:19:19.757(2)? (STDERR)  - [email protected] installed, [email protected] needed
W20160915-17:19:19.757(2)? (STDERR)  - [email protected] installed, [email protected] needed
W20160915-17:19:19.757(2)? (STDERR)  - [email protected] not installed.
W20160915-17:19:19.757(2)? (STDERR)  - [email protected] not installed.
W20160915-17:19:19.758(2)? (STDERR)  - [email protected] not installed.
W20160915-17:19:19.759(2)? (STDERR)  - [email protected] not installed.
W20160915-17:19:19.759(2)? (STDERR)  - [email protected] not installed.
W20160915-17:19:19.759(2)? (STDERR)  - [email protected] not installed.
W20160915-17:19:19.760(2)? (STDERR)  - [email protected] not installed.
W20160915-17:19:19.760(2)? (STDERR)  - [email protected] not installed.
W20160915-17:19:19.760(2)? (STDERR) 
W20160915-17:19:19.760(2)? (STDERR) Read more about installing npm peer dependencies:
W20160915-17:19:19.761(2)? (STDERR)   http://guide.meteor.com/using-packages.html#peer-npm-dependencies
W20160915-17:19:19.761(2)? (STDERR) 
W20160915-17:19:19.989(2)? (STDERR) /Users/ortiz/.meteor/packages/meteor-tool/.1.4.1_1.1h0re2h++os.osx.x86_64+web.browser+web.cordova/mt-os.osx.x86_64/dev_bundle/server-lib/node_modules/fibers/future.js:280
W20160915-17:19:19.989(2)? (STDERR)                         throw(ex);
W20160915-17:19:19.990(2)? (STDERR)                         ^
W20160915-17:19:19.990(2)? (STDERR) 
W20160915-17:19:19.990(2)? (STDERR) Error: Can't find npm module 'react-addons-transition-group'. Did you forget to call 'Npm.depends' in package.js within the 'modules-runtime' package?
W20160915-17:19:19.991(2)? (STDERR)     at Object.Npm.require (/Users/ortiz/Siti/tutorial/meteor/react/flowrouter/.meteor/local/build/programs/server/boot.js:198:17)
W20160915-17:19:19.991(2)? (STDERR)     at options.fallback (packages/modules-runtime/modules-runtime.js:21:1)
W20160915-17:19:19.991(2)? (STDERR)     at require (packages/modules-runtime/.npm/package/node_modules/install/install.js:88:1)
W20160915-17:19:19.993(2)? (STDERR)     at meteorInstall.node_modules.meteor.react-runtime.react-runtime.js (packages/react-runtime/react-runtime.js:29:20)
W20160915-17:19:19.993(2)? (STDERR)     at fileEvaluate (packages/modules-runtime/.npm/package/node_modules/install/install.js:153:1)
W20160915-17:19:19.993(2)? (STDERR)     at require (packages/modules-runtime/.npm/package/node_modules/install/install.js:82:1)
W20160915-17:19:19.993(2)? (STDERR)     at /Users/ortiz/Siti/tutorial/meteor/react/flowrouter/.meteor/local/build/programs/server/packages/react-runtime.js:79:15
W20160915-17:19:19.994(2)? (STDERR)     at /Users/ortiz/Siti/tutorial/meteor/react/flowrouter/.meteor/local/build/programs/server/packages/react-runtime.js:92:3
W20160915-17:19:19.994(2)? (STDERR)     at /Users/ortiz/Siti/tutorial/meteor/react/flowrouter/.meteor/local/build/programs/server/boot.js:292:10
W20160915-17:19:19.995(2)? (STDERR)     at Array.forEach (native)
=> Exited with code: 1
=> Your application is crashing. Waiting for file change.

Material-UI datePicker

How would one implement a solution for the Material UI DatePicker with this package? When using the simply ReactLayout.renader it seems to make it work in a weird manner, probably due to the fact that the datePicker instance creates a new body tag.

let {DatePicker} = mui;

MainLayout = React.createClass({
    // Required by Material UI
    childContextTypes: {
        muiTheme: React.PropTypes.object
    },
    getChildContext() {
        return {
            muiTheme: mui.Styles
                .ThemeManager
                .getMuiTheme(mui.Styles.LightRawTheme)
        };
    },
    render: function() {
        return (
            <DatePicker hintText="Portrait Dialog" />
        );
    }

});

2015-10-16 09_23_09-localhost_3000
DatePicker issue

callback after render.

I would like to have the functionality like react.render to have a callback after the layout is fully renderd.

like

ReactLayout.render(TodoApp, { children: <TodoMain />, // navbar : <div><NavbarAbout /><NavbarForm /></div> navbar : <ReactNavbar navbar={navbar}/> }, function(){ alert('yo'); });

React is undefined

Hello, I'm writing a local package with meteor-react-layout and i'm getting the error that React is not defined.
Here's my package.js:

// ...

Package.onUse(function(api) {
    api.versionsFrom('1.2.1');
    api.use('ecmascript');
    api.use('react');
    api.use('kadira:flow-router');
    api.use('kadira:react-layout');
    api.use('meteorflux:dispatcher');
    api.use('meteorflux:appstate');
    api.use('fourseven:scss');
    api.use('meta:susy');
    api.use('accounts-password');

    api.addFiles([
        'client/login_layout.jsx',
        'client/layout_store.js',
        'client/routes.js'
    ], 'client');
});

Multiple <head> and <body> tags

Hey I just updated to new version 1.4.0 and multiple and tags appearing on my app, which breaks it entirely.
screen shot 2015-10-16 at 00 46 19

PS: it was working fine just before the update.

Nested layouts

I'm building an app that has a main layout, and then several different areas which have their own 'sub layout' (nested inside the main layout) and then further 'sub layouts'. For example something like

// Group discussion view
<AppLayout>
    <GroupLayout >
        <DiscussionsLayout >
            <Discussion />
        </DiscussionsLayout >
    </GroupLayout >
</AppLayout>

// Group event view
<AppLayout>
    <GroupLayout >
        <CalendarLayout >
            <Event />
        </CalendarLayout >
    </GroupLayout >
</AppLayout>

I've managed to get this working easily by doing something like:

GroupLayout = React.createClass({
    render () {
        var self = this;
        var groupLayout = function () {
            return (
                <div>
                    <h1>Group</h1>
                    {self.props.content()}
                </div>
            )
        }

        return (
            <AppLayout content={groupLayout} />
        )
    }
});

// Similar thing for the discussions layout
...

and then I render it the normal way:

ReactLayout.render(DiscussionsLayout, {
    content() {
        return <Discussion />;
    }
});

This works, however, if I navigate from say .../discussions/:id (which renders <Discussion /> inside DiscussionsLayout) to .../discussions (which renders <DiscussionsList /> inside DiscussionsLayout), all of the layout components (AppLayout, GroupLayout...) get re-rendered. As opposed to doing something like:

React.render(<AppLayout></AppLayout>, document.body);
// Then when a user enters a group
React.render(<GroupLayout></GroupLayout>, document.getElementById("app-content"));
// When a user goes to .../discussions
React.render(<DiscussionsLayout><DiscussionsList /></DiscussionsLayout>, document.getElementById("group-content"));
// When a user goes to .../discussions/:id
React.render(<Discussion />, document.getElementById("discussions-content"));

This way only the template is rendered when a user navigates to .../discussions/:id, and the templates are not re-rendered.

I was wondering if there is a way to achieve something similar with ReactLayout? Basically the ability to render a component into an already rendered component.

How to pass data from Layout to child

Okay, I've got a small question. We have a route:

FlowRouter.route('/test', {
  name: 'admin.permissions.index',
  action: function () {
    ReactLayout.render(AdminLayout, {
      content: <AdminPermissionsIndex />
    });
  }
});

So, in the top AdminLayout we have getMeteorData() and render:

getMeteorData() {
  return {
    currentUser: Meteor.user()
  };
},
render() {
  <section>
    {this.props.content}
  </section>
}

Now I need to pass this.data.currentUser as props to its child (AdminPermissionsIndex). Am I doing it right and how can I do it?

Documentation Query

https://github.com/kadirahq/meteor-react-layout

In this url, there's a HomePage component which isn't defined in the code. But there's a component called Home defined.
So is the HomePage component an independent component assumed to be defined and referred
or
is it the Home component which is by accident referred as the HomePage component?

Components does not unmount upon route transition

I have two routes, however, each of the content components does not unmount upon changing route, as evidenced by logging componentDidUnmount.

This is problematic because I set up intervals that sync data between my database and external services, but this should only run on the /feed route. But without the unmount callback, I don't see how I can clear them in a non-hacky way

memberRoutes.route('/feed', {
  action: function() {
    ReactLayout.render(DashboardLayout, {
      content: <Feed/>
    });
  }
});

memberRoutes.route('/publish', {
  action: function() {
    ReactLayout.render(DashboardLayout, {
      content: <Publish/>
    });
  }
});

render html tags or markdown from db

Hello! How i can render html or markdown without translate tags to text? I try add marked to react component, render anything rendered to text

FlowRouter.route("/", {
    action: function () {
        ReactLayout.render(HomePage);
    }
});


{marked(this.data.page.content)}

How do you pass props down through ReactLayout and {this.props.content}?

So, I'm rending stuff using ReactLayout (as a 'layout manager'), and what I'm having problems understanding is...how are you supposed pass props down from App -> Layout -> Page, if you can't (I don't see how) pass props down through {this.props.content}?

Say I have a function thisFunc() in App that I want to pass down to a grandchild component...how're you supposed to go about that? Ordinarily, I'd just do something like , but since you're using {this.props.content} to render components...I don't know how the chain is supposed to work.

Insights?

SSR issue

Hi @arunoda
I got this error since React v0.14.x

Warning: React attempted to reuse markup in a container but the checksum was invalid. This generally means that you are using server rendering and the markup generated on the server was not what the client was expecting. React injected new markup to compensate which works but you have lost many of the benefits of server rendering. Instead, figure out why the markup being generated is different on the client or server:
 (client) he post list</span><span data-reactid=".
 (server) he post list</span><ul data-reactid=".x9

how to solve this ?

thanks

Meteor 1.3 - React is not defined when using npm React

I'm using React from npm with Meteor 1.3 and am having issues getting FlowRouter + Meteor React Layout working.

Exception from Tracker recompute function:
debug.js:41 ReferenceError: React is not defined
    at FlowRouter.route.action [as _action] (routes.jsx:4)
    at Route.callAction (route.js:51)
    at router.js:447
    at Object.Tracker.nonreactive (tracker.js:589)
    at router.js:431
    at Tracker.Computation._compute (tracker.js:323)
    at Tracker.Computation._recompute (tracker.js:342)
    at Object.Tracker._runFlush (tracker.js:481)
    at Object.Tracker.flush (tracker.js:441)
    at Router._invalidateTracker (router.js:489)

If you import React in my routes.jsx file, you get this

invariant.js:39 Uncaught Error: Invariant Violation: addComponentAsRefTo(...): Only a ReactOwner can have refs. 
You might be adding a ref to a component that was not created inside a component's `render` method, or you have multiple copies of React loaded (details: https://fb.me/react-refs-must-have-owner).
invariant @ invariant.js:39ReactOwner.addComponentAsRefTo @ ReactOwner.js:67attachRef @ ReactRef:23ReactRef.attachRefs @ ReactRef:42attachRefs @ ReactReconciler:21assign.notifyAll @ CallbackQueue.js:65ON_DOM_READY_QUEUEING.close @ ReactReconcileTransaction:81Mixin.closeAll @ Transaction.js:202Mixin.perform @ Transaction.js:149batchedMountComponentIntoNode @ ReactMount.js:282Mixin.perform @ Transaction.js:136ReactDefaultBatchingStrategy.batchedUpdates @ ReactDefaultBatchingStrategy:62batchedUpdates @ ReactUpdates.js:94ReactMount._renderNewRootComponent @ ReactMount.js:476wrapper @ ReactPerf.js:66ReactMount._renderSubtreeIntoContainer @ ReactMount.js:550ReactMount.render @ ReactMount.js:570wrapper @ ReactPerf.js:66(anonymous function) @ react_layout.js:69(anonymous function) @ react_layout.js:87(anonymous function) @ react_layout.js:86
debug.js:41 Exception from Tracker recompute function:

Unexpected token < in route render

I'm trying to render a react component from the router, but I'm getting the error SyntaxError: Unexpected token <. I'm probably just doing something silly, but I followed the example in the docs and it doesn't want to cooperate.

routes:

var admin = FlowRouter.group({
    prefix: '/admin'
});

admin.route( '/', {
    action: function() {
        ReactLayout.render( MainLayout, {
            content: <AdminArea />
        });
    }
});

Warning message as of React 0.14

The react package has been updated to 0.14, and as a result, React.render is no longer valid. For React 0.14 and up, it should be ReactDOM.render.

Preloader

How can I render a loading template while the current one is loading. I would like to have a preloader on each route (not specifically tied to mongo collections but let's say on assets load or page reload).

Best Place to Store Logged in State?

Hello:

I'm trying to figure out the best way to use this layout manager to store logged in state. Many components need to have a this.props.user (i.e. Meteor.user()) but this sits at the layout level, not at the individual component level (i.e. <Navbar />, etc.). Where should I put the `getMeteorDatacall for this, in an``` component or something? That would seem to defeat the purpose of using a layout manager at all....any guidance would be much appreciated!

Using multiple Layouts

Hey I don't see how to properly use multiple layouts. I have two layouts, but when using Flow Router to change the URL and try to load the new layout, it works but then gives this message:

Warning: render(): Target node has markup rendered by React, but there are unrelated nodes as well. This is most commonly caused by white-space inserted around server-rendered markup. react-runtime-dev.js?8fefd85d334323f8baa58410bac59b2a7f426ea7:21998 Warning: React attempted to reuse markup in a container but the checksum was invalid. This generally means that you are using server rendering and the markup generated on the server was not what the client was expecting. React injected new markup to compensate which works but you have lost many of the benefits of server rendering. Instead, figure out why the markup being generated is different on the client or server: (client) <body class="pushable (server) <header data-reactid=

And eventually this:

Exception from Tracker recompute function: Error: Invariant Violation: ReactMount: Root element ID differed from reactRootID.

What is the proper way to change layouts between pages?

ReactLayout renders app twice

Hi Arunoda,

I'm experiencing a weird issue with ReactLayout where it renders the same app twice.

Repo with all code is here:
https://github.com/tyusupov/meteor-react-layout-issue

Some details

  1. 2 React Apps are created
    react
  2. These apps are mounted on 2 divs myapp (expected) and react-root (unexpected).
  3. Content is displayed twice as well.
    divs

If FlowRouter block is uncommented in main.jsx then everything works as expected.

If ReactLayout is replaced with ReactDOM apps are rendered just once, which leads me to believe the issue is with ReactLayout.

Thank you very much in advance for looking into it,

Telman

Here is the code:

main.html
-------------------------------
<head>
    <title>My App</title>
</head>
<body>
    <div id="myapp"></div>
</body>

main.jsx:
-------------------------------
App = React.createClass({
    render() {
        return <ContentPage />
    }
});

ContentPage = React.createClass({
    render() {
        return <div>This is ContentPage</div>
    }
});

FlowRouter.route('/', {
    action() {
        ReactLayout.render(App);
    }
});

if (Meteor.isClient) {
    Meteor.startup(function () {
        ReactDOM.render(<App />, 
            document.getElementById('myapp'));
    });
};

where to put head/ meta tags etc

If i want to use this without blaze, where do i put the base things like <meta> tags, and content that usually goes into the <head> ?

i tried adding into a layout component, but it gets rendered inside the body it seems.

image

MainLayout = React.createClass({

    mixins: [],

    render() {
        return (
            <html>
            <head>
                <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
                <meta name="viewport" content="width=device-width, initial-scale=1"/>
            </head>

            <body>
            <div id="layout">
           ...

Pass callback to layout?

I love this package, but most React layout examples I've seen use a global <App /> container component which allows you to pass callbacks to it. Is there a way for me to pass callbacks to the layout component? I'm trying to trigger open/closing a menu that needs to sit outside of the main content and header, and I can't figure out how to bubble up the toggle event to the layout then back down to the <Menu /> component.

My layout looks like this:

C.MainLayout = React.createClass({
    showLeft: function() {
        this.refs.left.show();
    },

    showRight: function() {
        this.refs.right.show();
    },
    toggleMenu: function () {

    },
    render() {
        return (
            <div className="full-height">
                <C.Menu ref="right" alignment="right">
                    <C.MenuItem hash="first-page">First Page</C.MenuItem>
                    <C.MenuItem hash="second-page">Second Page</C.MenuItem>
                    <C.MenuItem hash="third-page">Third Page</C.MenuItem>
                </C.Menu>

                {this.props.header}

                {this.props.content}

                {this.props.footer}
            </div>
        )
    }
});

I want to trigger a callback from a button click in the rendered header component back up the layout and down to the menu to update it's state....

Adding React Components using api.addFiles

Is there any reason why ReactLayout doesn't doesn't seem to be able to render files added within a package using the api.addFiles method?

api.addFiles(['components/router.jsx','components/base_components.jsx'],['client', 'server']);

Issue using ReactLayout.render

Hi, sorry for posting this question here. Wasn't quite sure where was the best spot to post it.

While trying to pass a React component to the main layout content prop, I get "SyntaxError: Unexpected token <"

I tried to follow the guide in this repo. Note that I don't get the error if I user a simple string like "Hello" in content: . It renders and displays Hello correctly.
Thanks for your assistance!

My default route:
FlowRouter.route('/', {
name: 'Home',
action: function(params) {
ReactLayout.render(MainLayout, {content: });
}
});

My MainLayout (exactly like the guide):
MainLayout = React.createClass({
render() {
return(


            </header>
            <body>
                {this.props.content}
            </body>
            <footer>

            </footer>
        </div>
    );
}

});

My Home component:
Home = React.createClass({
render() {
return (


{this.props.welcome}



)
}
});

FlowRouter.go does not trigger ReactLayout.render

I'm trying to redirect unauthorized users to the homepage using Flowrouter.go, but it is still rendering the private page, even though the browser URL is indeed the homepage. Am I missing something?

Minimal example:

router.jsx

FlowRouter.route('/', {
  action() {
    ReactLayout.render(MainLayout, {text: 'Front Page - now change browser url to /private'});
  }
});

FlowRouter.route('/private', {
  action() {
    ReactLayout.render(MainLayout, {text: 'Users only page - this should not display for unauthorized users. Notice the url is / and not /private...'});
  }
});

main.jsx

MainLayout = React.createClass({  
  getInitialState(){
    if(!Meteor.user()) {
      FlowRouter.go('/');
    }
    return null;
  },
  render() {
    return (
      <div>
        <div className="container">
          {this.props.text}
        </div>
      </div>
    );
  }
});

Having extra meta and different tags on my html head section

How can I go about having the code below in my 'master' template? It is not clearly indicated in the docs and I believe the package uses a special tag for hooking the components onto the body tag.

<head>
    <meta http-equiv="content-type" content="text/html;charset=UTF-8"/>
    <meta charset="utf-8"/>
    <title>Meteor Admin</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
    <link rel="apple-touch-icon" href="/ico/60.png">
    <link rel="apple-touch-icon" sizes="76x76" href="/ico/76.png">
    <link rel="apple-touch-icon" sizes="120x120" href="/ico/120.png">
    <link rel="apple-touch-icon" sizes="152x152" href="/ico/152.png">
    <link rel="icon" type="image/x-icon" href="favicon.ico"/>
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-touch-fullscreen" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="default">
    <meta content="" name="description"/>
    <meta content="" name="author"/>
</head>

<body class="fixed-header ">
</body>

Do I simply have it in any page or there is a meteor way of ensuring that this file gets used as the main body holder?

React's getChildContext doesn't set child context properly?

If I have a simple root component in React

AppLayout = React.createClass({

  childContextTypes: {
    muiTheme: React.PropTypes.object
  },

  getChildContext: function() {
    return {
      muiTheme: ThemeManager.getCurrentTheme()
    };
  },

  render() {
    return (
      <div>
        { this.props.content }
      </div>
    )
  }
});

And a FlowRouter / ReactLayout setup like this

FlowRouter.route('/register', {
  name: 'register',
  action: function(params) {
    ReactLayout.render(AppLayout, { content: <AuthRegisterPage /> });
  }
});

Then within the render() method of AuthRegisterPage, this.context is undefined. However, if I don't use { this.props.content } and simply have <AuthRegisterPage /> within the AppLayout component then this.context returns {muiTheme: someobject} as I'd expect.

I'm not a react expert by any means. Am I missing anything?

react-root

I found out via an issue, but the docs don't mention that your root element should have an id="react-root", otherwise all this doesn't work. Because you can name your root element anything you want.

<div id="react-root"></div>

You might want to add that.

Can't comment code in layouts

<p>This is visible</p>
<!-- This raises an 'Unexpected Token' -->
/* This is visible */
// This is also visible

Is there a way I can add inline comments to react templates?

Uncaught Error: Invariant Violation: ReactMount: Two valid but unequal nodes with the same data-reactid

Hello Arunoda! You create greate packages for React. But i have some intresting bug.

When i click +add then click back, again click +add, again click back... n times)
2015-09-10 16-39-08 localhost 3000 opera

router.jsx

FlowRouter.route("/", {
    name: "list",
    action(params) {
        ReactLayout.render(Base, {
            content: <List/>
        });
    }
});
FlowRouter.route("/add", {
    name: "add",
    action(params) {
        ReactLayout.render(Base, {
            content: <Add/>
        });
    }
});

base.jsx

Base = React.createClass ({
    render() {
        return (
            <main>
                {this.props.content}
            </main>
        );
    }
});

list.jsx

List = React.createClass ({
    render() {
        return (
            <div>
                <a href={FlowRouter.path("add")}>+ add</a>
            </div>
        );
    }
});

add.jsx

Add = React.createClass ({
    render() {
        return (
            <div>
                <a href={FlowRouter.path("list")}>back</a>
                <form className="new-task" onSubmit={this.handleSubmit}>
                    <input placeholder="title" ref="title" type="text"/>
                    <input placeholder="city" ref="city" type="text"/>
                    <button>Save</button>
                </form>
          </div>
        );
      }
});

What wrong with code?

Testing repository here https://github.com/jmlv/meteor-react-flowrouter-test

ReactLayout rendering on top of BlazeLayout and vice versa

I have routes which use both BlazeLayout and ReactLayout. This is because I am using meteor-useraccounts/flow-routing which only supports Blaze at the time.

The Problem is when a browser calls a route which uses ReactLayout and the follows to a page with BlazeLayout or vice versa. The result is two layouts displayed one underneath the other.

FlowRouter.route('/', {
  name : "start",
  action: function(params, queryParams) {
    BlazeLayout.render("TopAppLayoutBlaze", { main: "HomePage" });
  }
});


FlowRouter.route("/tests/test01", {
  action: function() {
    ReactLayout.render(X.TopAppLayout, {
      content: <SimpleComponent name="Test" />
    })
  }
});

FlowRouter + Redux

I have standard FlowRouter + ReactLayout combo

  FlowRouter.route('/', {
    name: 'posts.list',
    action() {
      ReactLayout.render(MainLayoutCtx, {
        content: () => (<SearchPage />)
      });
    }
  });

but how can I wrap my whole layout into Provider from react-redux ?

const render = () => {
  ReactDOM.render((
    <Provider store={store}>
      <App />
    </Provider>
  ), document.getElementById('root'));
};

how to add React add-on components

some features of React are broken into components, for example the rather critical for animation
ReactTransitionGroup
http://facebook.github.io/react/docs/animation.html
http://facebook.github.io/react/docs/component-specs.html

How can these be added to a react-layout project?

var ReactCSSTransitionGroup = require('react-addons-css-transition-group');

usually the code has a require. perhaps we can just use npmRequire and it will find the package in npm?

also:
https://www.npmjs.com/package/velocity-transition-group

<link> and <meta tags>?

Hello:

I'm trying to follow the HTML5 boilerplate and I can't figure out how to properly include the and tags via JSX. Here's my layout code:

// layout.jsx
MainLayout = React.createClass({
  render() {
    return <div>
      <header>
        <meta charset="utf-8" />
        <meta http-equiv="x-ua-compatible" content="ie=edge" />
        <meta name="description" content="" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <link rel="apple-touch-icon" href="apple-touch-icon.png" />
        <link rel="stylesheet" href="css/normalize.css" />
        <link rel="stylesheet" href="css/main.css" />
        <title></title>
      </header>
      <main>
        {this.props.navbar}
        {this.props.content}
        {this.props.footer}
      </main>
      <footer>
      </footer>
    </div>
  }
});

//router.jsx
FlowRouter.route('/', {
action: function (params) {
ReactLayout.render(MainLayout, {
navbar: ,
content: ,
footer:


});
}
});

I added the /> closing tags to <meta> and <link> which removes the errors in my terminal, but I don't see them when viewing the source in the browser.

Any ideas?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.