简体   繁体   中英

Inline events not working (React+Express)

I understand there are similar questions out there and I have been through most of them.but I couldn't resolve my problem.

So I am trying out server side rendering with react and express and as the title suggests,I cant seem to get the event handlers working

After a couple of hours on google I reached a conclusion that I would need to render the application on the client side as well as the server side for the event handlers to work?how do i do that ? I know how to serve just the React app with web dev server without using SSR
but how do I render the application on the client as well as the server??

I am new to react and express I am quite lost at this moment there were some tutorials suggesting that I try hydrate() on the client side but still nothing ! how do I enable event handlers while still achieving server side rendering??

server file

 import {TextBlock} from "../components/textblock/textblock" const path = require("path") var express = require("express") var React = require("react") const ReactDOMServer = require('react-dom/server'); var app = express(); app.get("*", (req, res) => { const markup = ReactDOMServer.renderToString( <TextBlock /> ) res.send(`<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>React and Webpack4</title> </head> <body> <section id="index">${markup}</section> <script type="text/javascript" src="index_bundle.js"></script></body> </html> `) }) app.listen(3000, () => { console.log("server is listening"); }) 

**Client**

 import React from "react"; import ReactDOM from "react-dom"; import {TextBlock} from "../components/textblock/textblock" ReactDOM.hydrate(<TextBlock/>,document.getElementById("index")); 

**Webpack Config**

 const HtmlWebPackPlugin = require("html-webpack-plugin"); var path = require('path'); const htmlPlugin = new HtmlWebPackPlugin({ template: "./src/index.html", filename: "./index.html" }); const serverConfig = { entry: "./src/server/index.js", target: "node", output: { path: path.resolve(__dirname, ""), filename: 'server.js' }, module: { rules: [ { test: /\\.js$/, exclude: /node_modules/, use: { loader: "babel-loader" } }, { test: /\\.css$/, exclude: /node_modules/, use: [ { loader: 'style-loader' }, { loader: 'css-loader', options: { modules: true, importLoaders: 1, localIdentName: "[name]_[local]_[hash:base64]", sourceMap: true, minimize: true } } ] } ] } } const browserConfig = { entry: "./src/browser", output: { path: path.resolve(__dirname, 'dist'), filename: 'index_bundle.js' }, module: { rules: [ { test: /\\.js$/, exclude: /node_modules/, use: { loader: "babel-loader" } }, { test: /\\.css$/, exclude: /node_modules/, use: [ { loader: 'style-loader' }, { loader: 'css-loader', options: { modules: true, importLoaders: 1, localIdentName: "[name]_[local]_[hash:base64]", sourceMap: true, minimize: true } } ] } ] }, plugins: [htmlPlugin] } module.exports = [browserConfig, serverConfig] 

React Component

 import React from 'react'; import ReactDom from 'react-dom' export class TextBlock extends React.Component{ constructor() { super() this.state=({count:1}) } onComponentDidMount(){ console.log("component loaded") } increment(){ this.setstate({count:++this.state.count}) } getState(){ return this.state.count } render(){ return( <div> <div onClick={(e)=>{this.increment()}} style={{border:"solid red 2px"}}>{this.getState()}</div> </div> ) } } 
It this how it supposed to be?? how does react take over if I am sending a rendered components through express?when does it take over? Is there no way I could enable inline browser events? while still achieving server side rendering? Link to the Repo https://github.com/xxxgrime/ssrerror

u have to enable disst folder for server. as u can see in bunde javascript there is html not realy js so in your index.js

app.use(express.static('./dist'));

and you have another problem there

increment(){
  this.setstate({count:++this.state.count})
}

this is function context. use arrow function or binde this to the function in constructor

increment = () => {
  this.setstate({count:++this.state.count})
}

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