从Redux切换到MobX for React之后,我开始非常喜欢MobX。太棒了

MobX具有某种行为,即如果未在渲染中使用提供的可观察到的存储,则MobX不会更新组件。我认为通常这是一个很棒的行为,它使组件仅在实际更改时才渲染。

但是...我确实遇到过两种情况,这些情况是我不想或不需要在render方法中使用MobX可观察的,在这种情况下,我的MobX存储区的this.props.store不会得到更新。

在这种情况下,作为一种解决方法,我只是在render方法中引用了observable,但是我不认为这是一种非常干净的方法,并且我想知道是否有一种更干净的方法可以做到这一点?

此组件代码应解释更多我所要问的问题。
它是一个组件,可根据我在商店中看到的MobX来更改 body 溢出样式。

/*------------------------------------*\
  Imports
\*------------------------------------*/
import React from 'react';
import connectStore from 'script/connect-store';
import addClass from 'dom-helpers/class/addClass';
import removeClass from 'dom-helpers/class/removeClass';


/*------------------------------------*\
  Component
\*------------------------------------*/
class Component extends React.Component {

  constructor(props) {
    super(props);
    this.constructor.displayName = 'BodyClassSync';
  }

  componentDidMount() {
    this.checkAndUpdateMuiClass();
  }

  componentDidUpdate() {
    this.checkAndUpdateMuiClass();
  }

  checkAndUpdateMuiClass() {

    // This place is the only place I need latest MobX store...
    if (this.props.store.muiOverlay) {
      addClass(window.document.body, 'mod-mui-overlay');
    }

    else {
      removeClass(window.document.body, 'mod-mui-overlay');
    }

  }


  render() {

    // This is my workaround so the componentDidUpdate will actually fire
    // (with latest and updated store)
    // when the 'muiOverlay' observable changes in the MobX store
    // Is there any cleaner/better way to do this?
    this.props.store.muiOverlay;

    // This component doesn't and shouldn't render anything
    return null;

  }



}



/*------------------------------------*\
  Export
\*------------------------------------*/
const ComponentWithStore = connectStore(Component);
export default ComponentWithStore;

(注意:我不使用@decorators,而是在connectStore函数中使用ES5语法连接存储。如果在ES5中也能解决此问题,那将是非常棒的。)

最佳答案

您可以在componentDidMount中使用autorun并将其放在componentWillUnmount中,这样就不必在render方法中引用它。

class Component extends React.Component {
  constructor(props) {
    super(props);
    this.constructor.displayName = 'BodyClassSync';
  }

  componentDidMount() {
    this.dispose = autorun(() => {
      const { muiOverlay } = this.props.store;

      if (muiOverlay) {
        addClass(window.document.body, 'mod-mui-overlay');
      } else {
        removeClass(window.document.body, 'mod-mui-overlay');
      }
    });
  }

  componentWillUnmount() {
    this.dispose();
  }

  render() {
    return null;
  }
}

由于您实际上并没有在此组件中执行任何操作,因此您也可以将autorun直接放在您的商店中。

关于javascript - 在render方法中未使用可观察的情况时,如何使MobX更新组件?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51284202/

10-12 06:35