ReactJS以正确的方式绑定组件方法
ReactJS bind a component method the correct way
在组件中使用方法时,我正在尝试使用.bind()
。原因很简单:在一个循环中,我正在返回组件,并用一个调用方法的属性来扩展它们。但对于每个循环项,我都想用一些信息(比如键)来扩展this
对象。
示例:
项目.jsx
Items = React.createClass({
eventMethod() {
console.log('this event was triggered by key:', this.key);
},
items() {
let items = [];
let properties = {};
_.each(this.props.items, (itemData, key)=>{
properties.eventMethodInItem = this.eventMethod.bind(_.extend(this, {
key
}));
let {...props} = properties;
let item = <Item {...props} key={key} />;
items.push(item);
});
return items;
},
render() {
return(<div>{this.items()}</div>);
}
});
Item.jsx
Item = React.createClass(...);
在这种情况下(及其工作),当项目组件触发道具"eventMethodInItem"时,将调用我的方法"eventMethod",并且this.key
具有正确的值!
那么,现在的问题是什么?它运行得很完美,对吧?
是
但是ReactJS不希望我这样做。这就是ReactJS作为控制台日志告诉我的。
警告:bind():您正在将组件方法绑定到组件。React以高性能的方式自动为您执行此操作,因此您可以安全地删除此调用。参见项目
也许你认为像我这样把孩子添加到组件中是一种"糟糕"的方式,但在我的特殊情况下,我需要用这种方式来做——所以我需要把新信息绑定到一个方法上。
我不会假装我理解你在这里想做什么,但也许我无论如何都可以帮你澄清。
React获取在每个组件上找到的所有顶级方法,并自动将它们绑定到组件的上下文。
这防止了其他方法覆盖this
的上下文,因此,如果您试图重新绑定该方法,React会说"嘿,别担心。我已经得到了"——这就是您看到的警告。
假设真的想要这样做(每次通过重写eventMethodInItem
属性来更改外部properties
对象时)。
properties.eventMethodInItem = this.eventMethod.bind(_.extend(this, {
key
}));
然后,我看不出eventMethod
必须存在于组件上的任何原因,而不仅仅是在items
函数的范围内。
items() {
const eventMethod = function() {
console.log('this event was triggered by key:', this.key);
}
// ...
_.each(this.props.items, (itemData, key)=>{
properties.eventMethodInItem = eventMethod.bind(_.extend(this, {
key
}));
// ...
});
},
这样,你就不必为了让你的程序发挥作用而与React斗争。
React在使用React.createClass
时已经在自动绑定this
http://facebook.github.io/react/docs/interactivity-and-dynamic-uis.html#under-引擎盖自动绑定和事件委派
将绑定更改为
properties.eventMethodInItem = this.eventMethod.bind(null,key);
和你的eventMethod
到
eventMethod(key) {
console.log('this event was triggered by key:', key);
}
我还建议使用_.map
而不是_.each
items() {
return _.map(this.props.items, (itemData, key) => {
return <Item
handleEventMethod={this.eventMethod.bind(null,key)}
key={key} />;
});
},
良好的模式https://www.newmediacampaigns.com/blog/refactoring-react-components-to-es6-classes
之前:
class ExampleComponent extends React.Component {
constructor() {
super();
this. _handleClick = this. _handleClick.bind(this);
this. _handleFoo = this. _handleFoo.bind(this);
}
// ...
}
之后:
class BaseComponent extends React.Component {
_bind(...methods) {
methods.forEach( (method) => this[method] = this[method].bind(this) );
}
}
class ExampleComponent extends BaseComponent {
constructor() {
super();
this._bind('_handleClick', '_handleFoo');
}
// ...
}
这个话题的另一个好技巧http://egorsmirnov.me/2015/08/16/react-and-es6-part3.html
- react组件中的绑定方法
- 如何向onClick事件处理程序传递一个接受参数的函数,并且仍然将该函数绑定到组件's”;这个“;上下文
- 将事件绑定到其他UI组件's函数,在Kendo MVVM中
- 如何刷新'选项'ko多选组件中的绑定
- bind():您正在将一个组件方法绑定到该组件.React会自动为您执行此操作
- Ember组件:将attr绑定到每个属性中
- 如何将事件绑定到模式对话框上的组件
- 为什么Angular 1.5双向绑定在将作用域变量传递给组件绑定时失败
- 如何绑定'这'到react类之外的函数,后者是来自其他组件的回调
- Angular 1.5组件双向绑定不起作用
- AngualrJS:为什么组件范围不绑定
- Angular 1.5 嵌套组件绑定父值
- 通用角度组件 - 可选绑定
- 挖空绑定自定义组件,使其不与中心视图模型冲突
- Angular2 - 组件变量/组件类属性上的双向数据绑定
- 如何在 Angular 1.5 组件中等待绑定(没有 $scope.$watch)
- 反应组件中的绑定函数
- 两个网络组件之间的绑定:谷歌地图+地理定位
- ReactJS以正确的方式绑定组件方法
- 有条件地绑定组件状态