2017-08-25 2 views
0

Ich bin neu in Lernen zu erstellen Die Webserver-Anwendung mit Node-Express-React, aber ich konnte nicht vollständig reagieren. In diesem Code habe ich versucht, componentDidMount() Funktion in Reagieren zu verwenden, aber irgendwie dieses Stück Code feuert es nicht .. Gesucht den ganzen Weg zum Internet, aber konnte keine Möglichkeit finden, es nur mit Express Node und React zu verwenden. Haben über die Webpack gelernt, die Komplexität zu schaffen, stellt sich heraus, in meinem CodeReact.JS - Vollständig nicht im Knoten montieren - Express View Template

Hier ist der Server-Seite server.js Code meine Ansichten zu setzen und stopft

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"); 
}); 

und hier ist mein app.jsx-Code Reagieren

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; 

Ich habe den gleichen Code der React-Seite verwendet und eine HTML-Seite von Grund auf neu erstellt und dort kopiert und React.js und ReactDOM.js CDNs importiert und dieser gleiche Code funktioniert gut auf S Tatic HTML-Seiten, aber nicht auf Express Node Server aus irgendeinem Grund

Wenn es eine Möglichkeit gibt, kann ich componentDidMount() auslösen oder einen Zustand ändern, nachdem es gerendert wird ??

+0

Ich habe 'console.log()' verwendet, um zu überprüfen, ob es läuft oder nicht, und ich habe nichts erhalten, was eigentlich das nach bedeutet Rendering-Funktion wird nicht ausgelöst. Ich kopierte den Code in einem einfachen HTML und importierte CDNs von React in Skript-Tags und entdeckte, dass It 'componentDidMount()' läuft Fine. Aber der gleiche Code läuft nicht in einem Server Rendering –

+1

Haben Sie versucht Create React App? https://github.com/facebookincubator/create-react-app –

+0

'componentDidMount()' wird nach dem ersten 'render()' aufgerufen, so dass beim ersten Start der App 'state' nicht geändert wird bedeutet, dass Dinge nicht "montiert" wurden. Wenn Sie Ihre Anwendung das erste Mal starten, sehen Sie die Änderung von 'state' in' render() 'nicht. Wenn Sie später den Status ändern, können Sie das in 'render()' anzeigen. Sehen Sie sich den Reaktionslebenszyklus an und er wird Ihnen dabei helfen zu verstehen, wie react die Ansicht mit Backend-Daten aktualisiert: https://developmentarc.gitbooks.io/react-indepth/content/life_cycle/update/tapping_into_componentwillupdate.html –

Antwort

0

Meine Frage war, dass die Lifecycle-Methode von React nicht vollständig aufgerufen wurde, als ich versuchte, Express React View Template-Engine im obigen Code zu verwenden. Das Problem war, dass ich versuchte, den gesamten React-Code mit dieser einfachen Vorlage zu laden. Es lädt nur alle HTML. Ich habe nicht in die offiziellen React Docs der Installation geschaut. Meine Antwort war da. Danke an Mark Rabeys Antwort, die mich dazu brachte zu erkennen, was ich falsch gemacht hatte. Laut der offiziellen Dokumente auf Link https://facebook.github.io/react/docs/installation.html, dass mein Problem gelöst. Der Haupttext zum Installieren der richtigen Reaktion auf Ihre Anwendung lautet:

Sie müssen Ihre App nicht neu schreiben, um React zu verwenden.

Wir empfehlen das Hinzufügen von React zu einem kleinen Teil Ihrer Anwendung, wie ein einzelnes Widget, so dass Sie sehen können, ob es gut für Ihre Verwendung Fall funktioniert.

Während React ohne Build-Pipeline verwendet werden kann, empfehlen wir die Einstellung , damit Sie produktiver arbeiten können. Eine moderne build-Pipeline besteht typischerweise von:

  • einem Paket-Manager, wie zum Beispiel Garn oder NPM. Damit können Sie die Vorteile von ein riesiges Ökosystem von Drittanbietern Pakete nehmen und einfach zu installieren oder
    aktualisieren, um sie

  • A Bündler, wie webpack oder Browserify. Sie können den modularen Code schreiben und ihn in kleine Pakete bündeln, um die Ladezeit zu optimieren.

  • Ein Compiler wie Babel. Sie können damit modernen JavaScript-Code schreiben, der auch in älteren Browsern funktioniert.

Dies machte mir klar, dass die fehlende Sache in meinem Code die WebPack oder Broserify ist, und ich habe express-react-view zu entfernen, um meinen Voll funktionsfähig Reagieren zu machen. Danke an die Hilfe von RemarkableMark, die mich Schritt für Schritt bei der Einstellung Mein Reagieren auf diese PlayList (https://www.youtube.com/watch?v=k66bOHX8MnY&list=PLVgOtoUBG2md5HxaABCcnfstF88CPzUeD) begleitet hat Ich habe erfolgreich mein eigenes Template für React Connected mit Express-Node erfolgreich erstellt. Sie können es von diesem Github-Link erhalten github.com/Ahs-an-J/FirstExpressReactNodeLoginApp/tree/master/Express-React-Webpack. Vielen Dank die ganze Stack-Community hilft bei meiner ersten Frage: ')

1

Ich glaube, Ihr Problem ist, dass Sie nicht wirklich mit React verwenden, weil Sie nicht Webpack oder etwas anderes verwenden, um Ihren Code zu übertragen oder zu bündeln. Es ist nie auf der Seite geladen. Es gibt keine ReactDOM.render() oder irgendetwas, das benötigt wird, um React tatsächlich zu verwenden. Sie verwenden express-react-views, die nur als Jsx-View-Engine für Express funktioniert.

Von ihren README:

Dies ist ein Express-Ansicht-Engine, welche Komponenten auf dem Server Reagieren macht. Es rendert statisches Markup und unterstützt nicht Unterstützung, diese Ansichten auf dem Client zu montieren.

Reaction befindet sich nicht auf der Seite, daher werden die Lebenszyklusmethoden Ihrer Komponenten nie aufgerufen. Im Grunde nimmt es das, was die Komponente zuerst aussehen würde, und dient dem Browser als HTML.

+0

So wie kann ich React tatsächlich verwenden? .. ist es möglich, dass ich es ohne webpack verwenden könnte, da es Komplexität in meinem Code schafft .. etwas rein einfach zu implementierende Express-Methoden? –

+1

Es gibt andere Optionen wie Browserify, die stattdessen funktionieren könnten. Aber Webpack sollte dem Code keine Komplexität hinzufügen. Anders als einige Änderungen in Ihrem Build-Prozess sollte es Ihren Code nicht viel ändern. –

+0

Also gibt es einen leicht verständlichen Link, von dem Sie vielleicht wissen, dass er mir bei der Einrichtung von Webpack oder Browserify oder anderen helfen könnte? –

0

Wie Mark sagte, Sie sind nicht tatsächlich Render-Komponente in Ihrer Webseite, sondern eine einfache HTML-Markup von der jsx Templating-Engine generiert. Zuerst ändern wir Ihren Templating-Engine zu einem konventionelleren wie hjs. Damit sich Ihre Webanwendung genau wie eine React-App verhält, müssen Sie auf der Seite React installieren und dann Ihre Komponente mounten. Abgesehen davon verwenden wir auch node, um unsere Komponente auf dem Server zu rendern und diese an den Client zu senden. Wir werden also Server-Side-Rendering durchführen, und wir werden auch Komponenten in Ihrer Web-App bereitstellen, damit Ihre Lebenszyklus-Methoden ausgeführt werden können.

• Der wichtigste Punkt hier ist, dass die Komponente auf dem Server gerendert wird, aber wird nicht montiert, bevor es tatsächlich in den Browser montiert ist.

• Ein weiterer wichtiger Punkt wird zu beachten sein, dass keine DOM Manipulationen, da die gleiche Markup bereits auf dem Server gerendert wurde, auftreten und {{react}} mit reagieren Wurzel innerhalb an den Client übergeben.So wird das diff null Änderungen ergeben und das gesamte Rendering wird schnell sein. Dies ist eine ziemlich einfache Lösung und Sie müssen nicht viel Code ändern.

Ihre app.js sollte dies mögen.

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'}) 
    }); 
}); 


Ihre views/index.hjs sollte so.

<!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/[email protected]/dist/react.min.js"></script> 
    <script crossorigin src="https://unpkg.com/[email protected]/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> 


Schließlich Ihre Komponente App.jsx (public/jsx/App.jsx) sollte wie folgt aussehen. Bitte beachten Sie das isNode Flag, um unsere globalen Variablen zu ändern, da derselbe Code innerhalb des Browsers und des Servers ausgeführt wird.

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')) 
} 


Erfahren Sie mehr über weitere Ihrer Client-Seite Code browserify von here zu optimieren.

können Sie stecken auch in Ihren react-router und react-redux für eine noch bessere Serverseite Rendering Ihre Komponenten reagieren. (Wenn Sie planen, diese natürlich zu verwenden)

Das würde jedoch jetzt diese Antwort viel zu lange machen und es ist schon ziemlich lang.

Wirklich hoffe, es hilft!

Verwandte Themen