mobx5
- 建议在17及以下版本的react中去使用
- 建议在类组件中去使用mobx5
npm i -S mobx@5 mobx-react@5 --force
mobx5就是通过装饰器来完成对于属性和方法的装饰,来实现数据的响应式
- mobx5就是通过装饰器来完成对于属性和方法的装饰,来实现数据的响应式
定义文件夹数据源///定义mobx状态库
mobx/inde.js
// 定义一个类
class Store {
num = 100
setNum(n) {
this.num += n
}
}
// {store:store对象实例}
export default {
store: new Store() }
那么在入口文件中将数据源导入:在src/index.js入口文件中引入
mobx5提供了一个组件,将数据放在注入到组件中,将数据源导入到文件当中
index.js文件:
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
// mobx5
import {
Provider } from 'mobx-react'
// {store:store实例}
import store from './mobx'
ReactDOM.render(
<Provider {
...store}>
<App />
</Provider>,
document.getElementById('root')
)
使用:
import React, {
Component } from 'react'
import {
observer, inject } from 'mobx-react'
@inject(['store']) // 把store映射到this.props.store中
class App extends Component {
render() {
return (
<div>
<h1>{
this.props.store.num}</h1>
<button onClick={
e=>{
this.props.store.setNum(2)}}>+ +</button>
</div>
);
}
}
export default App;
可以发现数据没有响应,那么我们应该让数据变为响应式,组件也变为响应式。
- mobx-react提供了高阶组件observer来完成这项工作。
- observable:让组件变化是一个响应式的组件, 让此属性变成一个响应式的属性
- action让方法变为响应式的方法
响应式属性设置:
import {
observable, computed, action } from 'mobx'
// 定义一个类
class Store {
// 让此属性变成一个响应式的属性
@observable
num = 100
// action让成员方法,变成一个可以操作响应数据的方法
@action
setNum(n) {
this.num += n
console.log(n,this.num);
}
}
// {store:store对象实例}
export default {
store: new Store() }
完成响应式的使用写法:
import React, {
Component } from 'react'
import {
observer, inject } from 'mobx-react'
@inject(['store']) // 把store映射到this.props.store中
@observer // 1.让组件变化是一个响应式的组件
class App extends Component {
render() {
return (
<div>
<h1>{
this.props.store.num}</h1>
<button onClick={
e=>{
this.props.store.setNum(2)}}>+++</button>
</div>
);
}
}
export default App;
复杂数据类型的简单使用
import {
observable, computed, action } from "mobx";
// 定义一个类
class Store {
@observable
num = 100;
@action.bound
setNum(n) {
this.num += n;
console.log(n, this.num);
}
@observable
users = [];
@action
setUsers(data) {
this.users.push(data);
}
}
// {store:store对象实例}
export default {
store: new Store() };
<h2>{
JSON.stringify(this.props.store.users)}</h2>
<ul>
{
this.props.store.users.map(item=>(
<li key={
item.name}>name:{
item.name}</li>
))
}
</ul>
<button onClick={
e=>{
this.props.store.setUsers({
name:Date.now()})}}>添加姓名</button>
但是我们发现这个函数的使用直接前面需要写很多的链式寻找:我们解构之后需要注意的是修改方法里的this指向问题.bound解决这个问题:
虽然可以解决this指向问题,但一般解构后使用此方法才会有this指向不对问题。来解决
import {
observable, computed, action } from "mobx";
// 定义一个类
class Store {
@observable
num = 100;
@action.bound
setNum(n) {
this.num += n;
console.log(n, this.num);
}
@observable
users = [];
@action.bound
setUsers(data) {
this.users.push(data);
}
}
// {store:store对象实例}
export default {
store: new Store() };
假如现在有异步操作,当然可以直接在主程序中请求,然后在给mobx方法用来修改源数据:
但是不建议:可以在mobx方法中来完成对数据的异步操作;
尝试网络请求:
import {
observable, computed, action } from "mobx";
// 定义一个类
class Store {
@observable
users = [];
@action.bound
async setUsers(n) {
let data = await loadtime(n);//设置一个异步阻塞,发现可以实现网络请求
this.users.push({
name:Date.now()});
}
}
function loadtime(n){
return new Promise(_=>{
setTimeout(() => {
_("")
}, n);
})
}
// {store:store对象实例}
export default {
store: new Store() };
+++++++++++++++++++
app.jsx
<button onClick={
e=>{
setUsers(3000)}}>添加姓名</button>
n秒之后就完成数据的传入:可行
接着,如果脚手架没有设置axios或者http,可以使用webpack提供的全局fetch来进行网络请求,配置一个代理,完成对网络数据的模拟请求;
@action.bound
async setUsers(n) {
let data = await loadtime(n);//设置一个异步阻塞,发现可以实现网络请求
let ret = await (await fetch('/api/users?name='+n)).json()//网络请求模拟mock
console.log(ret.data);
this.users.push({
name:Date.now()},...ret.data);
}