React组件构造函数中使用this.setState及Firebase监听状态更新问题
React 相关问题解答
1. 能否在React组件的构造函数中使用this.setState?
简单说:不建议,也完全没必要。
构造函数的核心作用是初始化组件的state和绑定方法,这里直接给this.state赋值就够了,比如:
constructor(props) { super(props); // 直接初始化state,无需调用setState this.state = { count: 0 }; }
如果在构造函数里调用this.setState,不仅不会触发组件更新(毕竟组件还没完成挂载),而且属于多余操作,违背了React的设计逻辑,完全没必要这么做。
2. Firebase onValue监听器中this.setState报错的解决办法
你碰到的null is not an object(evaluating this.setState)问题,本质是回调函数里的this指向不对,和把监听器放在构造函数里无关,只是刚好你在构造函数里写了这段代码而已。给你几个实用的解决方法:
方法一:用箭头函数绑定this
箭头函数会自动继承外层作用域的this,把监听器的回调改成箭头函数就能解决:
constructor(props) { super(props); // 注意:不要手动写this.props = props,super(props)已经帮你处理好了 this.state = { data: null }; // 假设你的Firebase数据库引用是dbRef const dbRef = firebase.database().ref('your/target/path'); dbRef.on('value', (snapshot) => { // 这里的this会指向组件实例, setState就能正常调用了 this.setState({ data: snapshot.val() }); }); }
方法二:提前用bind绑定this到回调函数
如果习惯用普通函数,可以在构造函数里提前把回调的this绑定到组件实例:
constructor(props) { super(props); this.state = { data: null }; // 手动绑定this到回调函数 this.handleValueChange = this.handleValueChange.bind(this); const dbRef = firebase.database().ref('your/target/path'); dbRef.on('value', this.handleValueChange); } handleValueChange(snapshot) { this.setState({ data: snapshot.val() }); }
额外提醒:记得在组件卸载时移除监听器
为了避免内存泄漏,一定要在组件卸载的生命周期里移除Firebase的监听器:
componentWillUnmount() { const dbRef = firebase.database().ref('your/target/path'); // 如果用了方法二,要传绑定后的回调函数 dbRef.off('value', this.handleValueChange); // 如果用方法一的箭头函数,建议在构造函数里把监听器回调存为实例属性,比如this.listener = ... 再在这里off }
最后提个小细节:你代码里的this.props = props是多余的,super(props)已经会把props挂载到组件实例上了,手动赋值反而可能引发问题,记得删掉这行。
内容的提问来源于stack exchange,提问作者Arron J. Linton
相关产品推荐
相关产品推荐

