React.JS - 完全没有安装在节点 - 快速查看模板中

时间:2017-08-25 18:51:03

标签: node.js reactjs express

我是学习使用Node-Express-React创建Web服务器应用程序的新手,但我无法完全React。在本代码中我尝试使用 React中的componentDidMount()函数,但不知怎的,这段代码没有触发它。搜索了所有的方式到Internet,但无法找到一种方法只使用Express Node和React。已经了解了Webpack最终会在我的代码中创建复杂性

以下是设置我的观点和内容的服务器端server.js代码

const express = require('express');    
const app = express();    
const path = require('path');  
const React = require('react'); 
//setting my CSS folder (works fine)
app.use(express.static('static_assets'));

app.set('views','./views' );
app.set('view engine','jsx');
app.engine('jsx',require('express-react-views').createEngine());

app.get('/',function (req,resp){
    resp.render('app',{});
});

app.listen(5000,function(){
    console.log("Server Running at 5000");
});

这是我的React app.jsx代码

var React =require( 'react');

class Text extends React.Component{
    constructor(props){
        super(props);
        this.state = {speed:10};
    }
    componentDidMount(){
        this.setState({speed:30});
    }
    render(){
        return(
              <div>
             <h1>Hello </h1>
           {this.state.speed}
        </div>
        );
    }
} 
class app extends React.Component{
    constructor(props){
        super(props);
    }
    render(){
        return(
              <Text />
        );
    }
}

module.exports= app;

我使用了相同的React端代码并从头开始创建了一个HTML网页并将其复制到那里并导入React.jsReactDOM.js CDN,这个相同的代码在静态HTML页面上工作正常但是由于某种原因不在Express Node Server上

如果有任何方法可以使componentDidMount()触发或在渲染后进行状态更改?

3 个答案:

答案 0 :(得分:2)

我相信您的问题是因为您没有使用Webpack或其他内容来转换或捆绑您的代码,您使用React 它从未加载到页面上。没有ReactDOM.render()或任何实际使用React所需的东西。您正在使用express-react-views,它仅用作Express的jsx视图引擎。

来自README

  

这是一个Express视图引擎,它在服务器上呈现React组件。它呈现静态标记,不支持支持在客户端上安装这些视图。

React实际上并不在页面上,因此永远不会调用您的组件生命周期方法。基本上,它采用的是首先渲染的组件,并将其作为HTML提供给浏览器。

答案 1 :(得分:0)

正如Mark所说,您实际上并未在网页中呈现React组件,而是由jsx模板引擎生成的简单HTML标记。首先,我们将您的模板引擎更改为更常规的hjs。然后,为了使您的Web应用程序与React应用程序完全相同,我们需要在页面上安装React然后安装您的组件。除此之外,我们还将使用node在服务器上呈现我们的组件并将其发送到客户端。因此,我们将进行服务器端渲染,此外我们还将在您的Web应用程序中安装组件,以便您的生命周期方法可以运行。

•此处要注意的关键点是组件将在服务器上呈现,但在实际安装在浏览器中之前不会安装

•需要注意的另一个关键点是没有DOM 操作会发生,因为已经在服务器上呈现了相同的标记,并使用{{1}将其移交给react-root内的客户端}。因此差异将导致更改,整体渲染将很快。 这是一个相当简单的解决方案,您不必修改太多代码。

您的{{react}}应该这样。

app.js


您的var express = require('express'); var path = require('path'); var favicon = require('serve-favicon'); var logger = require('morgan'); var cookieParser = require('cookie-parser'); var bodyParser = require('body-parser'); var React = require('react'); var ReactDOM = require('react-dom/server'); // Will allow us to require .jsx files and to compile them. var jsx = require('node-jsx'); jsx.install(); var HelloMessageComponent = require('./public/jsx/App.jsx'); var HelloMessage = React.createElement(HelloMessageComponent); var app = express(); // view engine setup. Change this to hjs. app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'hjs'); // uncomment after placing your favicon in /public //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); app.use(logger('dev')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({extended: false})); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); app.use('/', function (req, res) { res.render('index', { react: ReactDOM.renderToString(HelloMessage, {name: 'John'}) }); }); 应该是这样的。

views/index.hjs


最后,您的组件 <!DOCTYPE html> <html> <head> <title>{{ title }}</title> <link rel='stylesheet' href='/stylesheets/style.css' /> <!-- Notice we're installing React here too via CDN. This will mount our already pre-rendered components --> <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script> <script crossorigin src="https://unpkg.com/react@15/dist/react.min.js"></script> <script crossorigin src="https://unpkg.com/react-dom@15/dist/react-dom.min.js"></script> </head> <body> <!-- This is where our server side rendered component code will go. --> <div id="react-root">{{react}}</div> <!-- Mount the same component inside the App.jsx file from the browser. --> <script src="/jsx/App.jsx" type="text/babel"></script> <!-- The server will create a full static markup inside the react-root div. --> <!-- Once we go to localhost:3000 from our browser the above script will run and mount the same component inside --> <!-- the same div. The key here is that no DOM manipulations will occur since the same markup has already been rendered --> <!-- inside react-root using {{react}}. So diff will result in zero changes and the rendering will be fast. --> <!-- Your React app is now mounted as well as rendered from the server. --> <!-- You can of course further optimize your text/babel script tag by using browserify to precompile and bundle. --> <!-- The link for bundling is down below! --> </body> </html> 应如下所示。请注意App.jsx (public/jsx/App.jsx)标志来修改我们的全局变量,因为相同的代码将在浏览器和服务器中运行。

isNode


了解有关使用here中的browserify进一步优化客户端代码的详情。

您还可以插入var isNode = typeof module !== 'undefined' && module.exports , React = isNode ? require('react') : window.React , ReactDOM = isNode ? require('react') : window.ReactDOM; class HelloMessage extends React.Component { constructor(props) { super(props); this.state = { name: this.props.name } } componentDidMount() { console.log('mounted'); setTimeout(() => { this.setState({name: 'Mustansir!'}) }, 5000); } handleClick() { alert('clicked!'); } render() { return <div onClick={this.handleClick}>Hello {this.state.name}</div>; } } if (isNode) { module.exports = HelloMessage } else { ReactDOM.render(<HelloMessage name="John"/>, document.getElementById('react-root')) } react-router,以获得更好的服务器端渲染React组件。 (如果你计划当然使用那些)

然而,现在这个答案会让这个答案太长,而且已经很长了。

真的希望它有所帮助!

答案 2 :(得分:0)

我的问题是,当我尝试在上面的代码中使用Express React View Template引擎时,React的生命周期方法没有被完全调用。问题是我尝试使用这个简单的模板加载所有React代码。它只加载所有HTML。我没有查看官方的React Docs of Installation我的答案就在那里。感谢 Mark Rabey的答案让我意识到我做错了什么。根据链接https://facebook.github.io/react/docs/installation.html的官方文档解决了我的问题。安装正确反应的主要文本是:

  

您无需重写应用即可开始使用React。

     

我们建议将React添加到应用程序的一小部分,例如   一个单独的小部件,因此您可以看到它是否适合您的使用   情况下。

     

虽然可以在没有构建管道的情况下使用React,但我们建议您进行设置   这样你就可以提高工作效率。通常是现代构建管道   包括:

     
      
  • 包管理器,例如Yarn或npm。它可以让你利用   一个庞大的第三方包生态系统,易于安装或者   更新它们

  •   
  • 捆绑包,例如webpack或Browserify。它可以让你编写模块   代码并将它们捆绑在一起形成小包,以优化加载时间。

  •   
  • 像Babel这样的编译器。它允许您编写现代JavaScript代码   仍旧适用于旧浏览器。

  •   

这让我意识到我的代码中缺少的东西是WebPack或Broserify,我必须删除express-react-view以使My React完全正常工作。感谢RemarkableMark的帮助指导我逐步在此PlayList上设置My React(https://www.youtube.com/watch?v=k66bOHX8MnY&list=PLVgOtoUBG2md5HxaABCcnfstF88CPzUeD)我已成功创建了自己的模板,并在Express上与Express-Node连接成功。你可以从这个Github链接获取它github.com/Ahsan-J/FirstExpressReactNodeLoginApp/tree/master/Express-React-Webpack。感谢所有Stack社区帮助解决我的第一个问题:')