检测可观察道具中的更新

时间:2017-01-19 07:55:56

标签: reactjs observable mobx mobx-react

我有一个具有可观察属性的组件:

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)

我的问题是,当观察变量发生变化时(通过点击按钮)永远不会调用componentWillReceivePropscomponentDidReceivePropsshouldComponentUpdate也不会。但是我可以在渲染的代码中看到颜色确实在商店中发生了变化。

2 个答案:

答案 0 :(得分:4)

tl; dr:使用componentWillUpdatecomponentDidUpdate

作为道具传递的对象Store永远不会改变,即使其内容发生变化。使用@observable的技巧是它将触发组件中的更新而不更改道具。因此,使用shouldComponentUpdatecomponentWillReceivePropscomponentDidReceiveProps等生命周期函数无法使用,因为当组件的支持或状态发生更改时,它们会被触发。 mobx doc在shouldComponentUpdate部分很好地解释了它。

因此,要捕获observable中的更新,我们必须在生命周期堆栈中更深入一些并使用componentWillUpdatecomponentDidUpdate

因此,代码应如下所示:

@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

上的文档