Recently the project directly started mobx, I was a little confused and did some research. Inject, observer and context are briefly introduced below:

Define store as follows:

export class UserStore implements IUserStore {

  @observable change = false;

  toggleChange = () => {
    this.change = !this.change;
  }
}

Copy the code

The modes of use in components are as follows:

1. Use only Inject

const Home1: React.SFC<IProps> = props => {
  const { toggleChange, change } = props;
  return (
    <div>
      <p>test function</p>
      <a onClick={toggleChange}>aaa</a>
      <p>{change ? "true" : "false"}</p>
    </div>
  );
};

export default inject((stores: GlobalStores) => ({
  toggleChange: stores.userstore.toggleChange,
  change: stores.userstore.change
}))(withRouter(Home1));
Copy the code

Since the underlying inject invokes an Observer, it is also possible to implement only Inject. If only inject is used, the parameter of Inject must be an object composed of required attributes; otherwise, the Observer cannot be used.

2. Inject and Observer

const Home1: React.SFC<IProps> = props => {
  const { toggleChange, change } = props.userstore;
  return (
    <div>
      <p>test function</p>
      <a onClick={toggleChange}>1aaa</a>
      <p>{change ? "true" : "false"}</p>
    </div>
  );
};

export default inject((stores: GlobalStores) => ({
  userstore: stores.userstore
}))(withRouter(observer(Home1)));
Copy the code

When inject and observer are used together, the parameter of Inject can be an object composed of required objects. Because the Observer monitors changes in the attributes used.

3. Use a mixture of observer and context, and class defines components

class Home1 extends React.Component<IProps> {
  static contextTypes = {
    mobxStores: PropTypes.object
  };

  render() {
    console.log(this.context, this.props, "111");
    const {
      mobxStores: {
        userstore: { toggleChange, change }
      }
    } = this.context;
    return (
      <div>
        <p>test class</p>
        <a onClick={toggleChange}>btn</a>
        <p>{change ? "true" : "false"}</p> </div> ); }}export default withRouter(observer(Home1));
Copy the code

Mobx is implemented based on context, so use the Observer and context to get the store passed from the root node

4. Use a mixture of observer and context, function defines components

const Home1: React.SFC<IProps> = (props, context) => {
  const {
    mobxStores: {
      userstore: { toggleChange, change }
    }
  } = context;
  return (
    <div>
      <p>test function</p>
      <a onClick={toggleChange}>aaa</a>
      <p>{change ? "true" : "false"}</p>
    </div>
  );
};

Home1.contextTypes = {
  mobxStores: PropTypes.object
};
export default withRouter(observer(Home1));
Copy the code