我有一个具有可观察属性的组件:
class Store {
@observable color = "red"
}
const store = new Store();
@observer
class MyComponent extends React.Component {
componentWillReceiveProps(nextProps) {
// Not called!
console.log("Component will receive props", nextProps.store.color)
}
componentDidMount() {
console.log("Component did mount", this.props.store.color)
}
changeColor = () => {
this.props.store.color = (this.props.store.color==="red")? "blue":"red";
};
render() {
return <div>
color: {this.props.store.color}
<button onClick={this.changeColor}>Change color</button>
</div>
}
};
ReactDOM.render(<MyComponent store={store} />, document.body)
我的问题是,当观察变量发生变化时(通过点击按钮)永远不会调用componentWillReceiveProps
,componentDidReceiveProps
或shouldComponentUpdate
也不会。但是我可以在渲染的代码中看到颜色确实在商店中发生了变化。
答案 0 :(得分:4)
tl; dr:使用componentWillUpdate
和componentDidUpdate
作为道具传递的对象Store
永远不会改变,即使其内容发生变化。使用@observable
的技巧是它将触发组件中的更新而不更改道具。因此,使用shouldComponentUpdate
,componentWillReceiveProps
和componentDidReceiveProps
等生命周期函数无法使用,因为当组件的支持或状态发生更改时,它们会被触发。 mobx doc在shouldComponentUpdate
部分很好地解释了它。
因此,要捕获observable中的更新,我们必须在生命周期堆栈中更深入一些并使用componentWillUpdate
和componentDidUpdate
。
因此,代码应如下所示:
@observer
class MyComponent extends React.Component {
componentWillReceiveProps(nextProps) {
// Not called!
console.log("Component will receive props", nextProps.store.color)
}
componentWillUpdate(nextProps) {
console.log("Component will update", nextProps.store.color)
}
componentDidMount() {
console.log("Component did mount", this.props.store.color)
}
changeColor = () => {
this.props.store.color = (this.props.store.color==="red")? "blue":"red";
};
render() {
return <div>
color: {this.props.store.color}
<button onClick={this.changeColor}>Change color</button>
</div>
}
};
JS Bin:http://jsbin.com/voqugezaya/edit?js,console,output
在封面下,mobx-react
使用forceUpdate
函数触发组件重新渲染,而无需更改其道具中的对象(仅更改其内容)。
此外,mobx引入了一个新功能,这对调试很有帮助:componentWillReact
。
答案 1 :(得分:0)
是否应该使用mobx生命周期钩子函数? (例如:componentWillReact)。请参阅https://mobx.js.org/refguide/observer-component.html
上的文档