0

i'm new with react, so i'm experiencing some troubles understanding what is wrong in my code. I'm writing basic web app with node js express and reactjs. I use a library for react: 'react-dynamic-list' but same thing happens if i require my own code from another file. This is my server.js :

var express = require('express');
var app = express();
var path = require('path');
require('babel-register')({
    presets: ['es2015', 'react']
});

app.engine('jade', require('jade').__express);
app.set('view engine', 'jade');
app.use(express.static(__dirname + '/public'));

var React = require("react");
var ReactDOM = require('react-dom/server');

var dList = require('./public/dynamicList.js');
var List = React.createFactory(dList.List);
app.get('/list', function(req, res){
var data = [
  {some data}
 ];
  res.render('list', {
   react: ReactDOM.renderToString(List({data, adapter}))
  });
});

this is component file:

var isNode = typeof module !== 'undefined' && module.exports
,React = isNode ? require('react') : window.React 
,ReactDOM = isNode ? require('react') : window.ReactDOM;

var DynamicList = require('react-dynamic-list/lib/List');

var List = React.createClass({
    handleClick: function(){
      console.log("clicked!");
    },
    componentDidMount:function(){
      console.log("mounted");
    },
    render: function(){
      return (
         <div>
          <DynamicList data={this.props.data} adapter={this.props.adapter} onClickRow={()=>{this.handleClick()}}/>
          <div onClick={this.handleClick}>COMMON!</div>
          </div>
      );
    }
});
if (isNode) {
  exports.List = List;
} else {
  ReactDOM.render(<List/>, document.getElementById('list'));
}

and this is template file

  doctype
  html
  head
    title Super reactive thing
    body
    div(id='list')!= react

    script(src='https://fb.me/react-0.14.0.js')
    script(src='https://fb.me/react-dom-0.14.0.js')
    script(src='https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js')

    script(src='/bundle.js', type='text/javascript')
    // script(src='/dynamicList.js', type='text/babel')

Normally in a last one i would use the same file '/dynamic List.js' in browser as in node but require() doesn't supported by browser so i used browserify with this command:

browserify -t [ babelify --presets [ react ] ] public/mainPage.js -o public/bundle.js

After all, click event doesn't happen not on row not on div and "mounted" never go to console, what am i getting wrong? Would be grateful for any help!

zo_chu
  • 355
  • 3
  • 14

2 Answers2

0

Your client side code is not being served properly, check your template links. Also, you dont need to use a factory.

Rob Wilkinson
  • 296
  • 1
  • 7
  • You were right there was a space in template! Now it's mounting correctly. Why shouldn't i use factory? – zo_chu Mar 20 '16 at 09:51
0

The way you are including the React component file (with isNode, etc.) isn't meant to be used in conjunction with browserify. You are essentially packaging the entire React library up in bundle.js, and isNode won't work properly within a browserify bundle (it evaluates to true even within a browser environment, and the window object will be unavailable, so it's not using the React libraries from the CDN.)

There could be ways to make this work with extra if/else statements, but you are requiring another React component from within this file, which makes that difficult.

To continue setting your project up this way you'll need to (at least) use a browserify shim for React. Take a look at: How do I exclude the "require('react')" from my Browserified bundle?

Basically, once you start using browserify or webpack to compile your JSX file(s) for the browser, you will need a different approach to setting up the project files than the one you started off using.

Community
  • 1
  • 1
firasd
  • 171
  • 1
  • 6
  • Thank you! Now it's getting much more clear to me. But if i'd like to use first approuch with if/else and without browserify is there a way to call my component from file on the client side? Or this is a bad idea anyway? – zo_chu Mar 19 '16 at 13:16
  • Because it seems very convenient to run the same code in browser and in node with the if/else cheching – zo_chu Mar 20 '16 at 09:53
  • To continue setting things up this way you would need to get the other component as a standalone compiled .js file to get it to load in the browser and then just call it in a script tag. But maybe I'm mistaken: looking at your other comment on the other answer, did you get this working using browserify with the problem turning out to be a space in the jade template? – firasd Mar 20 '16 at 23:53
  • But how can i put a js in if/else statement without 'require' that's what not very clear. I've got it working with browserify and without if/else. And the space thing was just a bug i found after component mounted. But according to this approach i have a very similar code on server and on client and also bundle file witch seems a bit inconvenient and not very DRY. But may be it's how react app supposed to look like. – zo_chu Mar 21 '16 at 08:03
  • Yeah once your dependencies like React, etc. are bundled in this way you can remove the ` – firasd Mar 26 '16 at 00:19