Mobx入门(二)

2019-08-28  本文已影响0人  隐号骑士

概念回顾

observable 类似于 store
observer 是装饰后的react组件
action 用来改变 observable 的状态

Class声明 Observerable

class AppState {
    @observable timer = 2
    @action clearTimer() {
        this.timer = 0
    }
}

var appState = new AppState()
@observer
class App extends React.Component {
  componentDidMount() {
    this.props.appState.timer++

  }
  render() {
    return (
      <div>
        <div className="App">
          <h1>Time passed: {this.props.appState.timer}</h1>
        </div>
      </div>
    );
  }
};

ReactDOM.render(<App appState={appState} />, document.getElementById('root'));

组件内定义局部observerable

@observer
class TodoList extends React.Component {
  @observable newTodoTitle = "";

  render() {
    return (
      <div>
        <form onSubmit={this.handleFormSubmit}>
          New Todo:
          <input
            type="text"
            value={this.newTodoTitle}
            onChange={this.handleInputChange}
          />
          <button type="submit">Add</button>
        </form>
        <hr />
        <ul>
          {this.props.store.todos.map(todo => (
            <Todo todo={todo} key={todo.id} />
          ))}
        </ul>
        Tasks left: {this.props.store.unfinishedTodoCount}
      </div>
    );
  }

  @action
  handleInputChange = e => {
    this.newTodoTitle = e.target.value;
  };

  @action
  handleFormSubmit = e => {
    this.props.store.addTodo(this.newTodoTitle);
    this.newTodoTitle = "";
    e.preventDefault();
  };
}

computed

class AppState {
    @observable timer = 2
    @computed get timessTwo() {
        return this.timer * 2
    }
    set timessTwo(timessTwo) {
        this.timer = timessTwo / 2
    }
}
@observer
class App extends React.Component {
  componentDidMount() {
    this.props.appState.timessTwo++
  }
  render() {
    return (
      <div>
        <div className="App">
          <h1>Time passed: {this.props.appState.timer}</h1>
          <h2>after times 2 :{this.props.appState.timessTwo}</h2>
        </div>
      </div>
    );
  }
};

autorun & reaction

监听

autorun(() => {
    console.log(appState.timer)
})
const reaction1 = reaction(
    () => appState.timer ,
    timer => console.log(`reaction 1: ${timer}`)
);

开发工具

cnpm i mobx-react-devtools
import DevTools from "mobx-react-devtools";

{process.env.NODE_ENV !== 'production' ? <DevTools /> : null}

严格模式

import { configure } from "mobx";
configure({ enforceActions: true }) // 不允许在action之外进行状态修改

异步

1 runInAction

mobx.configure({ enforceActions: true })

class Store {
    @observable githubProjects = []
    @observable state = "pending" // "pending" / "done" / "error"

    @action
    fetchProjects() {
        this.githubProjects = []
        this.state = "pending"
        fetchGithubProjectsSomehow().then(
            projects => {
                const filteredProjects = somePreprocessing(projects)
                // 将‘“最终的”修改放入一个异步动作中
                runInAction(() => {
                    this.githubProjects = filteredProjects
                    this.state = "done"
                })
            },
            error => {
                // 过程的另一个结局:...
                runInAction(() => {
                    this.state = "error"
                })
            }
        )
    }
}

2 await/async

class Store {
    @observable githubProjects = []
    @observable state = "pending" // "pending" / "done" / "error"

    @action
    async fetchProjects() {
        this.githubProjects = []
        this.state = "pending"
        try {
            const projects = await fetchGithubProjectsSomehow()
            const filteredProjects = somePreprocessing(projects)
            // await 之后,再次修改状态需要动作:
            runInAction(() => {
                this.state = "done"
                this.githubProjects = filteredProjects
            })
        } catch (error) {
            runInAction(() => {
                this.state = "error"
            })
        }
    }
}

3 flow(generator function)

class Store {
    @observable githubProjects = []
    @observable state = "pending"

    fetchProjects = flow(function * () { // <- 注意*号,这是生成器函数!
        this.githubProjects = []
        this.state = "pending"
        try {
            const projects = yield fetchGithubProjectsSomehow() // 用 yield 代替 await
            const filteredProjects = somePreprocessing(projects)
            // 异步代码块会被自动包装成动作并修改状态
            this.state = "done"
            this.githubProjects = filteredProjects
        } catch (error) {
            this.state = "error"
        }
    })
}

tip

使用大量的小组件

@observer 组件会追踪它们使用的所有值,并且当它们中的任何一个改变时重新渲染。 所以你的组件越小,它们需要重新渲染产生的变化则越小;这意味着用户界面的更多部分具备彼此独立渲染的可能性。

脚手架

https://github.com/mobxjs/mobx-react-boilerplate

上一篇下一篇

猜你喜欢

热点阅读