我有一个令我心烦意乱的问题,我有一个学校项目,我决定使用Express和React。问题是我有一个按钮,并且由于服务器渲染,事件没有绑定。
我给了你以下的文件。
Button.jsx
import React from 'react';
class Button extends React.Component {
clickEventHandler = (e) => {
console.log(123);
this.props.onClick(e);
}
render(){
return (
<button className="btn btn-default" onClick={this.clickEventHandler.bind(this)}>{this.props.Text}</button>
);
}
}
export default Button;
DataWrapper.jsx
import React, {Component} from 'react';
class DataWrapper extends Component {
getChildContext () {
return {
data: this.props.data
};
}
render () {
return this.props.children;
}
}
DataWrapper.childContextTypes = {
data: React.PropTypes.object.isRequired
};
export default DataWrapper;
Users.jsx
import React, {Component} from 'react'
import Button from './components/Button.jsx'
var ModalHeader = React.createClass({
render: function () {
return (
<div className="modal-header">
{this.props.title}
<button type="button" className="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
)
}
});
var ModalBody = React.createClass({
render: function () {
return (
<div className="modal-body">
{this.props.content}
</div>
)
}
});
var ModalFooter = React.createClass({
render: function () {
return (
<div className="modal-footer">
<button type="button" className="btn btn-primary">Submit</button>
</div>
)
}
});
var Modal = React.createClass({
render: function () {
return (
<div className="modal fade">
<div className="modal-dialog">
<div className="modal-content">
<ModalHeader title="Modal Title"/>
<ModalBody content="Modal Content"/>
<ModalFooter/>
</div>
</div>
</div>
)
}
});
class Users extends Component {
constructor(props, context) {
super(props, context);
this.state = context.data;
}
showModal(e) {
console.log(e.target);
//$(this.refs.modal.getDOMNode()).modal();
}
render() {
return (
<div>
<div className="row header-row">
<div className="col-md-2 text-center">
<span className="header-title">Pseudo</span>
</div>
<div className="col-md-2 text-center">
<span className="header-title">Email</span>
</div>
<div className="col-md-1 text-center">
<span className="header-title">Age</span>
</div>
<div className="col-md-2 text-center">
<span className="header-title">Nom</span>
</div>
<div className="col-md-2 text-center">
<span className="header-title">Prenom</span>
</div>
<div className="col-md-2 text-center">
<span className="header-title">Bannir</span>
</div>
</div>
{this
.state
.Users
.map((user) => {
return <div className="row">
<div className="col-md-2 text-center">
<span>{user.pseudo}</span>
</div>
<div className="col-md-2 text-center">
<span>{user.email}</span>
</div>
<div className="col-md-1 text-center">
<span>22</span>
</div>
<div className="col-md-2 text-center">
<span>{user.nom}</span>
</div>
<div className="col-md-2 text-center">
<span>{user.prenom}</span>
</div>
<div className="col-md-1 text-center">
<span>Ban</span>
</div>
<div className="col-md-1 text-center">
<Button Text="Test" onClick={(e) => this.showModal(e)} />
</div>
</div>;
})}
<Modal ref="modal"/>
</div>
);
}
};
Users.contextTypes = {
data: React.PropTypes.object.isRequired
}
export default Users;
Router.jsx
import express from 'express';
import redis from 'redis';
import request from 'request-promise';
import React from 'react';
import {renderToString} from 'react-dom/server';
import {RouterContext, match, createRoutes} from 'react-router';
import DataWrapper from '../client/data_wrapper.jsx';
import appRouter from '../client/router.jsx';
const routes = createRoutes(appRouter());
const router = express.Router();
let options = {
host: 'localhost',
port: '32768'
}
// The client stashes the password and will reauthenticate on every connect.
let client = redis.createClient(options);
client.on("error", function (err) {
console.log("Error " + err);
});
client.on("connect", function () {
console.log('Connected');
});
router.use(function (req, res, next) {
if (req.url !== '/login') {
client
.exists(req.sessionID, function (err, reply) {
if (reply !== 1) {
res.redirect(302, '/login')
res.end();
} else {
let token;
client.get(req.sessionID, function (err, reply) {
req.session.token = reply
next()
});
}
})
} else {
next()
}
});
router.get('/', (req, res) => {
match({
routes,
location: req.url
}, (error, redirectLocation, renderProps) => {
if (error) {
res
.status(500)
.send(error.message);
} else if (redirectLocation) {
res.redirect(302, redirectLocation.pathname + redirectLocation.search);
} else if (renderProps) {
const content = renderToString(<RouterContext {...renderProps}/>);
res.render('index', {
title: 'Express',
data: false,
content
});
} else {
res
.status(404)
.send('Not Found');
}
});
});
router.get('/home', (req, res) => {
match({
routes,
location: req.url
}, (error, redirectLocation, renderProps) => {
if (error) {
res
.status(500)
.send(error.message);
} else if (redirectLocation) {
res.redirect(302, redirectLocation.pathname + redirectLocation.search);
} else if (renderProps) {
const content = renderToString(<RouterContext {...renderProps}/>);
res.render('index', {
title: 'Express',
data: false,
content
});
} else {
res
.status(404)
.send('Not Found');
}
});
});
router.get('/login', (req, res) => {
match({
routes,
location: req.url
}, (error, redirectLocation, renderProps) => {
if (error) {
res
.status(500)
.send(error.message);
} else if (redirectLocation) {
res.redirect(302, redirectLocation.pathname + redirectLocation.search);
} else if (renderProps) {
const content = renderToString(<RouterContext {...renderProps}/>);
res.render('login', {
title: 'Login',
data: false,
content
});
} else {
res
.status(404)
.send('Not Found');
}
});
});
router.post('/login', (req, res) => {
let requestOptions = {
method: 'POST',
uri: 'http://MY_API/api/connection',
body: {
pseudo: req.body.Username,
password: req.body.Password
},
json: true
}
request(requestOptions).then((body) => {
console.log(req.sessionID)
req.session.cookie.expires = 3600 * 24;
client.set(req.sessionID, body.token);
client.expire(req.sessionID, 3600 * 24);
match({
routes,
location: '/home'
}, (error, redirectLocation, renderProps) => {
if (error) {
res
.status(500)
.send(error.message);
}
const content = renderToString(<RouterContext {...renderProps}/>);
res.render('index', {
title: 'Express',
data: false,
content
});
});
});
});
router.get('/users', (req, res) => {
let requestOptions = {
method: 'GET',
uri: 'http://My_API/api/users/',
headers: {
"x-access-token": req.session.token
},
json: true
}
request(requestOptions).then((body) => {
match({
routes,
location: req.url
}, (error, redirectLocation, renderProps) => {
if (error) {
res
.status(500)
.send(error.message);
} else if (redirectLocation) {
res.redirect(302, redirectLocation.pathname + redirectLocation.search);
} else if (renderProps) {
var users = {
"Users": body
};
//renderProps = React.createFactory(renderProps)
const content = renderToString(<DataWrapper data={ users }><RouterContext {...renderProps}/></DataWrapper>);
res.render('users', {
title: 'Express',
data: body,
content: content,
users: body
});
} else {
res
.status(404)
.send('Not Found');
}
});
});
});
module.exports = router;
app.js(快速入境点)
require('babel-register');
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 nodejsx = require("node-jsx").install();
var router = require('./routes/router');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// 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());
var session = require('express-session')
app.use(cookieParser());
app.use(session({
secret: 'schhhh', // just a long random string
resave: false,
saveUninitialized: true
}));
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', router);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
.babelrc
{
"presets": ["es2015", "react", "stage-0"]
}
webpack.config.js
var path = require('path');
var nodeExternals = require('webpack-node-externals');
module.exports = [
{
target: 'node',
entry: './client/app.jsx',
output: {
filename: 'app.js',
library: "require",
path: path.join('public/javascripts/')
},
module: {
loaders: [
{
exclude: /(node_modules|bower_components)/,
test: /\.jsx?$/,
loader: 'babel',
query: {
presets: ["react", "es2015", "stage-0"]
}
}, {
exclude: /(node_modules|bower_components)/,
test: /\.js$/,
loader: 'babel'
}
]
}
}, {
name: 'client',
target: 'web',
context: path.join(__dirname, 'client'),
entry: {
index: ['babel-polyfill', './users.jsx']
},
output: {
path: path.join(__dirname, 'public/javascripts/'),
filename: 'app.bundle.js'
},
module: {
loaders: [
{
exclude: /(node_modules|bower_components)/,
test: /\.html$/,
loader: 'raw'
}, {
exclude: /(node_modules|bower_components)/,
test: /\.css$/,
loader: 'style'
}, {
exclude: /(node_modules|bower_components)/,
test: /\.css$/,
loader: 'css'
}, {
exclude: /(node_modules|bower_components)/,
test: /\.jsx?$/,
loader: 'babel'
}
]
},
}
];
请帮助我,让我变得疯狂