Ger*_*los 7 flux reactjs reactjs-flux
我在reactjs-flux编写一个简单的应用程序,一切正常,除了我收到来自reactjs的警告,告诉我我在未安装的组件上调用setState.
我已经弄明白这是因为没有从商店中删除组件被挂钩的changelisteners componentWillUnmount.我知道这一点,因为当我打开监听器列表时,Eventemitter我会看到应该被销毁的监听器,并且当我多次挂载/卸载相同的组件时,列表会变大.
我从我的BaseStore粘贴代码:
import Constants from '../core/Constants';
import {EventEmitter} from 'events';
class BaseStore extends EventEmitter {
// Allow Controller-View to register itself with store
addChangeListener(callback) {
this.on(Constants.CHANGE_EVENT, callback);
}
removeChangeListener(callback) {
this.removeListener(Constants.CHANGE_EVENT, callback);
}
// triggers change listener above, firing controller-view callback
emitChange() {
this.emit(Constants.CHANGE_EVENT);
}
}
export default BaseStore;
Run Code Online (Sandbox Code Playgroud)
我从遇到此错误的组件中粘贴相关代码(但它适用于所有组件):
@AuthenticatedComponent
class ProductsPage extends React.Component {
static propTypes = {
accessToken: PropTypes.string
};
constructor() {
super();
this._productBatch;
this._productBatchesNum;
this._activeProductBatch;
this._productBlacklist;
this._searchById;
this._searchingById;
this.state = this._getStateFromStore();
}
componentDidMount() {
ProductsStore.addChangeListener(this._onChange.bind(this));
}
componentWillUnmount() {
ProductsStore.removeChangeListener(this._onChange.bind(this));
}
_onChange() {
this.setState(this._getStateFromStore());
}
}
Run Code Online (Sandbox Code Playgroud)
这让我非常疯狂.有任何想法吗?
谢谢!
Tom*_*omW 21
精简版: expect(f.bind(this)).not.toBe(f.bind(this));
更长的解释:
问题的原因是EventEmitter.removeListener要求您传递先前注册过的功能EventEmitter.addListener.如果您将引用传递给任何其他函数,则它是一个无声的无操作.
在您的代码中,您将传递this._onChange.bind(this)给addListener.bind返回绑定到此的新函数.然后,您将丢弃对该绑定函数的引用.然后你尝试删除绑定调用创建的另一个新函数,它是一个无操作,因为它从未添加过.
React.createClass自动绑定方法.在ES6中,您需要在构造函数中手动绑定:
@AuthenticatedComponent
class ProductsPage extends React.Component {
static propTypes = {
accessToken: PropTypes.string
};
constructor() {
super();
this._productBatch;
this._productBatchesNum;
this._activeProductBatch;
this._productBlacklist;
this._searchById;
this._searchingById;
this.state = this._getStateFromStore();
// Bind listeners (you can write an autoBind(this);
this._onChange = this._onChange.bind(this);
}
componentDidMount() {
// listener pre-bound into a fixed function reference. Add it
ProductsStore.addChangeListener(this._onChange);
}
componentWillUnmount() {
// Remove same function reference that was added
ProductsStore.removeChangeListener(this._onChange);
}
_onChange() {
this.setState(this._getStateFromStore());
}Run Code Online (Sandbox Code Playgroud)
有各种简化绑定的方法 - 你可以使用ES7 @autobind方法装饰器(例如npm上的autobind-decorator),或编写你在构造函数中调用的autoBind函数autoBind(this);.
在ES7中,您(希望)能够使用类属性来获得更方便的语法.如果你喜欢作为第一阶段提案http://babeljs.io/docs/plugins/transform-class-properties/的一部分,你可以在Babel中启用它.然后,您只需将事件侦听器方法声明为类属性而不是方法:
_onChange = () => {
this.setState(this._getStateFromStore());
}
Run Code Online (Sandbox Code Playgroud)
因为_onChange的初始化程序是在构造函数的上下文中调用的,所以箭头函数会自动绑定this到类实例,因此您只需将其this._onChange作为事件处理程序传递,而无需手动绑定它.
| 归档时间: |
|
| 查看次数: |
3867 次 |
| 最近记录: |