先开看一个例子:
用@observer装饰一个组件,也就是定义了一个响应式组件;用@observable装饰一个变量,就是定义了一个响应式变量。
无需在使用state,就可以改变组件内部的状态。
observer 函数/装饰器可以用来将 React 组件转变成响应式组件。 它用 mobx.autorun 包装了组件的 render 函数以确保任何组件渲染中使用的数据变化时都可以强制刷新组件。
import React from 'react';
import './App.css';
import { observable } from 'mobx';
import { observer } from 'mobx-react';
@observer
class App extends React.Component {
@observable value = '1';
render(){
return (<div>
APP
<input value={this.value} onChange={(e) => this.value = e.target.value}/>
{this.value}
</div>);
}
}
export default App;
action:
任何应用都有动作。动作是任何用来修改状态的东西。 使用MobX你可以在代码中显式地标记出动作所在的位置。 动作可以有助于更好的组织代码。
Inject:
- 如果不使用
Provider
配合inject
的话,代码相对多一些,需要自己的管理 - 如果使用
Provider
配合inject
,就没有那么麻烦了,把多个store,配到根上,子组件通过inject
自动注入;
Inject代码:
下面示例中,Provider中的属性props = {.. store},也等于:
在子组件中就可以通过inject注入这些provider的属性了,这样子组件中就有了这些属性。
例如:
@inject(‘friend’)
@inject(‘post’)
@inject(‘friend’, ‘post’)
import React from 'react';
import ReactDOM from 'react-dom';
import * as serviceWorker from './serviceWorker';
import store from './store';
import App from './App';
import { Provider } from 'mobx-react';
ReactDOM.render(
<Provider {...store}>
<App/>
</Provider>,
document.getElementById('root'));
serviceWorker.unregister();
例子:
store中friend的代码:声明了一个Friend类,类中的变量要用@observable修饰,表示是一个响应式变量。@computed表明是一个计算属性或方法,用于优化性能。手动生成一个Friend类的实例,然后export。
import {observable, computed} from 'mobx';
import post from './post';
class Friend {
@observable list = [
{
id: 1,
name: 'David'
},
{
id: 2,
name: 'Jim'
},
{
id: 3,
name: 'Bob'
},
];
@observable activeId = 1
@computed get friendPost() {
return post.list.filter((item) => item.friendId === this.activeId);
}
}
const friend = new Friend();
export default friend;
post的代码类似:
@action修饰的function表明是一个action,用于修改状态数据。
import { observable, action } from 'mobx';
const addForm = {
title: '',
content: '',
friendId: ''
};
class Post {
@observable addForm = {
...addForm
};
@observable
list = [
{
title: 'Hello David!',
content: 'A happy day 1',
id: 1,
friendId: 1
},
{
title: 'Hello DD!',
content: 'A happy day 2',
id: 2,
friendId: 1
},
{
title: 'Hello Xiao!',
content: 'A happy day 3',
id: 3,
friendId: 1
},
];
@action
handleAdd(){
this.list.push({...this.addForm});
}
@action
clear(){
this.addForm = {...addForm};
}
}
const post = new Post();
export default post;
store代码:
表明stote中的数据有两个key,一个是friend,另一个是post,值分别对应于刚才创建的类对象。
import friend from './friend';
import post from './post';
export default {
friend: friend,
post: post
};
view/friend 的代码:
Friend component要用@observer修饰,并且要注入store中friend属性,在使用时候解构出来方便使用。
import React, { Component } from 'react';
import { observer, inject } from 'mobx-react';
@inject('friend')
@observer
class Friend extends Component {
render() {
const {
friend
} = this.props;
return (<div>
{friend.list.map((item) => <span
onClick={() => friend.activeId=item.id}
key={item.id}>
{item.name} |
</span>)}
</div>);
}
}
export default Friend;
view/post 代码:
类似friend代码结构。
import React, {Component} from 'react';
import {inject, observer} from 'mobx-react';
@inject('friend')
@observer
class Post extends Component {
render() {
const { friend } = this.props;
console.log(friend.activeId);
return (<div>
{friend.friendPost.map((item) => <div key={item.title}>
<h4>{item.title}</h4>
<p>{item.content}</p>
</div>)}
</div>);
}
}
export default Post;
view/action代码:
代码中post.handleAdd(),来调用post示例中用@action修饰的handleAdd方法。
import React, {Component} from 'react';
import { inject, observer } from 'mobx-react';
@inject('post')
@observer
class Action extends Component {
render() {
const { post } = this.props;
return (<div>
<div>
<input placeholder='title' value={post.addForm.title} onChange={(e) => post.addForm.title = e.target.value}/>
</div>
<div>
<input placeholder='content' value={post.addForm.content} onChange={(e) => post.addForm.content = e.target.value}/>
</div>
<div>
<input type='number' placeholder='friend Id' value={post.addForm.friendId} onChange={(e) => post.addForm.friendId = parseInt(e.target.value)}/>
</div>
<button onClick={(e) => {
post.handleAdd()
}}>Add</button>
</div>);
}
componentWillUnmount(){
const { post } = this.props;
post.clear();
}
}
export default Action;
App组件代码:
注入了两个属性’friend’, ‘post’,只是想输出看下他们的值。根据需要注入或不注入。
import React, {Component} from 'react';
import './App.css';
import { observer, inject } from 'mobx-react';
import Friend from './views/friend';
import Post from './views/post';
import Action from './views/action';
@inject('friend', 'post')
@observer
class App extends Component {
render(){
console.log(this.props, 'this.props');
return (<div>
<h2>Friend List</h2>
<Friend/>
<h2>All Post</h2>
<Post/>
<Action/>
</div>);
}
}
export default App;
index文件:
引入了Provider,并且属性值为 friend={friend}, post={post},然后可以在App组件,或者其任意子组件中注入使用。
import React from 'react';
import ReactDOM from 'react-dom';
import * as serviceWorker from './serviceWorker';
import store from './store';
import App from './App';
import { Provider } from 'mobx-react';
ReactDOM.render(
<Provider {...store}>
<App/>
</Provider>,
document.getElementById('root'));
serviceWorker.unregister();
最终UI: