我有简单的hello world代码:
import React from 'react';
class ShoppingList extends React.Component {
getComponent(event) {
console.log('li item clicked!');
event.currentTarget.style.backgroundColor = '#ccc';
}
render() {
return (
<div className="shopping-list">
<h1>This is props name: {this.props.name}</h1>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
<div>
<ul>
<li onClick={this.getComponent.bind(this)}>Component 1</li>
</ul>
</div>
</div>
);
}
}
module.exports = ShoppingList;
当我点击<li>Component 1</li>
时,没有任何反应。
为什么呢?页面成功呈现。没有错误,
一切
没问题,但处理程序无法正常工作。
FULL EXAMPLE
:
节点服务器: app.js
var express = require('express');
var app = express();
var routes = require('./routes/index')
app.use('/', routes);
app.set('port', process.env.PORT || 9080);
app.use('/public', express.static(__dirname + '/public/'));
app.set('views', __dirname + '/views');
app.set('view engine', 'jsx');
app.engine('jsx', require('express-react-views').createEngine());
var server = app.listen(app.get('port'), function () {
console.log(__dirname + '/public/');
console.log('STARTED');
});
路线: index.js:
var express = require('express');
var router = express.Router();
router.get('/', function (req, res) {
res.render('index', {name:"AHOJ"});
});
module.exports = router;
index.jsx:
import React from 'react';
var ShoppingList = require('./components/ShoppingList');
class IndexComponent extends React.Component {
constructor(props) {
super(props);
this.getComponent = this.getComponent.bind(this);
}
getComponent(event) {
console.log('li item clicked!');
event.currentTarget.style.backgroundColor = '#ccc';
}
render() {
return (
<DefaultLayout name={this.props.name}>
<div>
<ul>
<li onClick={this.getComponent}>Component 1</li>
</ul>
</div>
</DefaultLayout>
)
}
};
module.exports = IndexComponent;
master.jsx:
var React = require('react');
class MasterLayout extends React.Component {
render() {
return (
<html lang="eng">
<head>
<meta charset="utf-8" />
<title>{this.props.name}</title>
<meta name="description" content="The HTML5 Herald" />
<meta name="author" content="SitePoint" />
<link rel="stylesheet" type="text/css" href="/public/css/main.css" />
</head>
<body>
{this.props.children}
</body>
</html>
)
}
};
module.exports = MasterLayout;
我希望,这个代码对你来说很明确,它的hello world项目。完整示例是课程ShoppingList
:IndexComponent
。
我阅读了一些教程,我认为,我的代码是正确的,页面成功呈现。没有错误,
一切
没问题,但处理程序无法正常工作。
<li>
不数据重新
答案 0 :(得分:3)
这不是你应该如何构建你的组件。这样做:
class ShoppingList extends React.Component {
constructor(props) {
super(props);
this.getComponent = this.getComponent.bind(this);
}
getComponent(event) {
console.log('li item clicked!');
event.currentTarget.style.backgroundColor = '#ccc';
}
render() {
return (
<div className="shopping-list">
<h1>This is props name: {this.props.name}</h1>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
<div>
<ul>
<li onClick={this.getComponent}>Component 1</li>
</ul>
</div>
</div>
);
}
}
我在这里做的是为组件创建了一个构造函数。构造函数调用super()
,以便它可以使用this
关键字。
在构造函数中使用时,super关键字单独出现,必须在使用this关键字之前使用。此关键字也可用于调用父对象上的函数。
然后,它调用.bind(this)
并将getComponent
绑定到组件。现在onClick
处理程序可以更改为onClick={this.getComponent}
。将对.bind()
的调用移动到构造函数会提供显着的性能提升,因为现在该方法只绑定一次,而不是在每次渲染组件时反复绑定。
额外提示:将getComponent
的参数名称从event
更改为其他内容。 event
不是JS中的保留关键字,但它 但在某些IE版本中是全局的。追踪相当棘手的错误。
答案 1 :(得分:1)
只是一个FYI,您还可以使用无状态功能组件并使用存储在常量中的方法:
import React from 'react';
import { render } from 'react-dom';
const clickHandler = e => {
console.log(`${e.target} \n element clicked!!! \n -------`);
};
const App = () => (
<div>
<ul>
<li style={{border:"solid 1px"}}
onClick={clickHandler}
>Click Me</li>
</ul>
<h2 onClick={clickHandler}>I'm a header</h2>
</div>
);
render(<App />, document.getElementById('root'));
如果您点击<li>
控制台将显示:
[object HTMLLIElement]
element clicked!!!
-------
如果您单击标题,它将显示:
[object HTMLHeadingElement]
element clicked!!!
-------
但是当然如果您需要扩展组件类,您可以使用它,但如果您使用目标而不是当前目标,则不需要创建构造函数:
https://developer.mozilla.org/es/docs/Web/API/Event/currentTarget
这是没有构造函数的代码:
import React, {Component} from 'react';
import { render } from 'react-dom';
class App extends Component {
clickHandler(e){
console.log(e.target);
e.target.style.backgroundColor = '#ccc';
}
render(){
return(
<div>
<ul>
<li style={{border:"solid 1px"}}
onClick={this.clickHandler}
>Click Me</li>
</ul>
<h2 onClick={this.clickHandler}>I'm a header</h2>
</div>
);
}
}
render(<App />, document.getElementById('root'));
正如您所看到的,它适用于两种情况:
答案 2 :(得分:0)
将你的李改为:
<li onClick={() => this.getComponent}>Component 1</li>
这种方式在实际点击时会正确引用它,而不是在渲染时引用它。