image.png

    先开看一个例子:
    用@observer装饰一个组件,也就是定义了一个响应式组件;用@observable装饰一个变量,就是定义了一个响应式变量。
    无需在使用state,就可以改变组件内部的状态。

    observer 函数/装饰器可以用来将 React 组件转变成响应式组件。 它用 mobx.autorun 包装了组件的 render 函数以确保任何组件渲染中使用的数据变化时都可以强制刷新组件。

    1. import React from 'react';
    2. import './App.css';
    3. import { observable } from 'mobx';
    4. import { observer } from 'mobx-react';
    5. @observer
    6. class App extends React.Component {
    7. @observable value = '1';
    8. render(){
    9. return (<div>
    10. APP
    11. <input value={this.value} onChange={(e) => this.value = e.target.value}/>
    12. {this.value}
    13. </div>);
    14. }
    15. }
    16. export default App;

    action:
    任何应用都有动作。动作是任何用来修改状态的东西。 使用MobX你可以在代码中显式地标记出动作所在的位置。 动作可以有助于更好的组织代码。

    Inject:

    1. 如果不使用Provider配合inject的话,代码相对多一些,需要自己的管理
    2. 如果使用Provider配合inject,就没有那么麻烦了,把多个store,配到根上,子组件通过inject自动注入;

    Inject代码:

    下面示例中,Provider中的属性props = {.. store},也等于:

    在子组件中就可以通过inject注入这些provider的属性了,这样子组件中就有了这些属性。
    例如:
    @inject(‘friend’)
    @inject(‘post’)
    @inject(‘friend’, ‘post’)

    1. import React from 'react';
    2. import ReactDOM from 'react-dom';
    3. import * as serviceWorker from './serviceWorker';
    4. import store from './store';
    5. import App from './App';
    6. import { Provider } from 'mobx-react';
    7. ReactDOM.render(
    8. <Provider {...store}>
    9. <App/>
    10. </Provider>,
    11. document.getElementById('root'));
    12. serviceWorker.unregister();

    例子:
    store中friend的代码:声明了一个Friend类,类中的变量要用@observable修饰,表示是一个响应式变量。@computed表明是一个计算属性或方法,用于优化性能。手动生成一个Friend类的实例,然后export。

    1. import {observable, computed} from 'mobx';
    2. import post from './post';
    3. class Friend {
    4. @observable list = [
    5. {
    6. id: 1,
    7. name: 'David'
    8. },
    9. {
    10. id: 2,
    11. name: 'Jim'
    12. },
    13. {
    14. id: 3,
    15. name: 'Bob'
    16. },
    17. ];
    18. @observable activeId = 1
    19. @computed get friendPost() {
    20. return post.list.filter((item) => item.friendId === this.activeId);
    21. }
    22. }
    23. const friend = new Friend();
    24. export default friend;

    post的代码类似:

    @action修饰的function表明是一个action,用于修改状态数据。

    1. import { observable, action } from 'mobx';
    2. const addForm = {
    3. title: '',
    4. content: '',
    5. friendId: ''
    6. };
    7. class Post {
    8. @observable addForm = {
    9. ...addForm
    10. };
    11. @observable
    12. list = [
    13. {
    14. title: 'Hello David!',
    15. content: 'A happy day 1',
    16. id: 1,
    17. friendId: 1
    18. },
    19. {
    20. title: 'Hello DD!',
    21. content: 'A happy day 2',
    22. id: 2,
    23. friendId: 1
    24. },
    25. {
    26. title: 'Hello Xiao!',
    27. content: 'A happy day 3',
    28. id: 3,
    29. friendId: 1
    30. },
    31. ];
    32. @action
    33. handleAdd(){
    34. this.list.push({...this.addForm});
    35. }
    36. @action
    37. clear(){
    38. this.addForm = {...addForm};
    39. }
    40. }
    41. const post = new Post();
    42. export default post;

    store代码:

    表明stote中的数据有两个key,一个是friend,另一个是post,值分别对应于刚才创建的类对象。

    1. import friend from './friend';
    2. import post from './post';
    3. export default {
    4. friend: friend,
    5. post: post
    6. };

    view/friend 的代码:

    Friend component要用@observer修饰,并且要注入store中friend属性,在使用时候解构出来方便使用。

    1. import React, { Component } from 'react';
    2. import { observer, inject } from 'mobx-react';
    3. @inject('friend')
    4. @observer
    5. class Friend extends Component {
    6. render() {
    7. const {
    8. friend
    9. } = this.props;
    10. return (<div>
    11. {friend.list.map((item) => <span
    12. onClick={() => friend.activeId=item.id}
    13. key={item.id}>
    14. {item.name} |
    15. </span>)}
    16. </div>);
    17. }
    18. }
    19. export default Friend;

    view/post 代码:

    类似friend代码结构。

    1. import React, {Component} from 'react';
    2. import {inject, observer} from 'mobx-react';
    3. @inject('friend')
    4. @observer
    5. class Post extends Component {
    6. render() {
    7. const { friend } = this.props;
    8. console.log(friend.activeId);
    9. return (<div>
    10. {friend.friendPost.map((item) => <div key={item.title}>
    11. <h4>{item.title}</h4>
    12. <p>{item.content}</p>
    13. </div>)}
    14. </div>);
    15. }
    16. }
    17. export default Post;

    view/action代码:
    代码中post.handleAdd(),来调用post示例中用@action修饰的handleAdd方法。

    1. import React, {Component} from 'react';
    2. import { inject, observer } from 'mobx-react';
    3. @inject('post')
    4. @observer
    5. class Action extends Component {
    6. render() {
    7. const { post } = this.props;
    8. return (<div>
    9. <div>
    10. <input placeholder='title' value={post.addForm.title} onChange={(e) => post.addForm.title = e.target.value}/>
    11. </div>
    12. <div>
    13. <input placeholder='content' value={post.addForm.content} onChange={(e) => post.addForm.content = e.target.value}/>
    14. </div>
    15. <div>
    16. <input type='number' placeholder='friend Id' value={post.addForm.friendId} onChange={(e) => post.addForm.friendId = parseInt(e.target.value)}/>
    17. </div>
    18. <button onClick={(e) => {
    19. post.handleAdd()
    20. }}>Add</button>
    21. </div>);
    22. }
    23. componentWillUnmount(){
    24. const { post } = this.props;
    25. post.clear();
    26. }
    27. }
    28. export default Action;

    App组件代码:

    注入了两个属性’friend’, ‘post’,只是想输出看下他们的值。根据需要注入或不注入。

    1. import React, {Component} from 'react';
    2. import './App.css';
    3. import { observer, inject } from 'mobx-react';
    4. import Friend from './views/friend';
    5. import Post from './views/post';
    6. import Action from './views/action';
    7. @inject('friend', 'post')
    8. @observer
    9. class App extends Component {
    10. render(){
    11. console.log(this.props, 'this.props');
    12. return (<div>
    13. <h2>Friend List</h2>
    14. <Friend/>
    15. <h2>All Post</h2>
    16. <Post/>
    17. <Action/>
    18. </div>);
    19. }
    20. }
    21. export default App;

    index文件:

    引入了Provider,并且属性值为 friend={friend}, post={post},然后可以在App组件,或者其任意子组件中注入使用。

    1. import React from 'react';
    2. import ReactDOM from 'react-dom';
    3. import * as serviceWorker from './serviceWorker';
    4. import store from './store';
    5. import App from './App';
    6. import { Provider } from 'mobx-react';
    7. ReactDOM.render(
    8. <Provider {...store}>
    9. <App/>
    10. </Provider>,
    11. document.getElementById('root'));
    12. serviceWorker.unregister();

    最终UI:
    image.png