简体   繁体   中英

React js isomorfic app doesn't mount a component with require()

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!

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM