mobx学习笔记05——使用mobx-react

mobx-react的作用是将react组件转换为对可观察数据的反应。

首先在项目下安装所需依赖:npm i react react-dom prop-types mobx-react -S

         (为了编译JSX语法) npm install --save-dev @babel/preset-react

1)将项目中的index.js文件扩展名改为jsx,并修改webpack.config.js中对应的后缀名,以及新装依赖的配置代码。

"presets": [
   	            ["@babel/preset-env",{"useBuiltIns":"entry"}],
   		    ["@babel/preset-react"]
   	      ]

2)创建两个React组件,并把它们显示到页面上,然后通过mobx来修改状态,进而实现驱动视图。

3)在index.jsx中导入所需的各个组件。

Store类用于存储数据

import { observable,action } from 'mobx';
import React,{ Component } from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';

class Store {
	cache = {queue: []}
}

const store = new Store();

//Bar Foo
class Bar extends Component {
	static propTypes = {
		queue: PropTypes.array
	};
	render() {
		const queue = this.props.queue;
		return <span>{queue.length}</span>;
	}
}

class Foo extends Component {
	static propTypes = {
		cache: PropTypes.object
	};
	render() {
		const cache = this.props.cache;
		return <div><Bar queue={cache.queue} /></div>;
	}
}

ReactDOM.render(<Foo cache={store.cache}/>,document.querySelector('#root'));  

浏览器页面中显示0,表示编译成功,React项目能够正常运行。

 

 4)为该React程序添加mobx支持

第一步,把Store中的数据转换为可观察数据

class Store {
	@observable cache = {queue: []}
}

如果这时有警告⚠️,是因为因为可观察的数组并不是真正的数组,从mobx-react中引入PropTypes即可,为了避免与react官方提供的PropTypes重名,将mobx-react中的PropTypes换一个名字。

import {PropTypes as observablePropTypes} from 'mobx-react'
queue: observablePropTypes.observableArray //queue: PropTypes.array

5)把对可观察数据的修改都封装到action中  

在Store中声明action方法

class Store {
	@observable cache = {queue: []}

	@action.bound refresh() {
		this.cache.queue.push(1);
	}
}  

将refresh传入Foo组件

ReactDOM.render(<Foo cache={store.cache} refresh={store.refresh}/>,document.querySelector('#root'));  

在Foo组件中声明button

render() {
		const cache = this.props.cache;
		return <div><button onClick={this.props.refresh}>Refresh</button><Bar queue={cache.queue} /></div>;
	}

但这时点击Refresh按钮并没有反应......

这是因为React组件并没有重新渲染,这时就需要mobx-react登场了!mobx-react可以将React组件的render方法包装成autorun,那我们执行action时是不是就可以触发组件重新渲染了呢?

首先从mobx-react中导入observer方法,该方法也是一个decorator修饰器,与普通修饰器不同的是,它不是用来修饰类成员的,而是用来修饰类本身的,修饰的类为React组件类。

import { observer } from 'mobx-react';

接下来尝试修饰一下Foo组件:

@observer
class Foo extends Component {
	static propTypes = {
		cache: PropTypes.object
	};
	render() {
		const cache = this.props.cache;
		return <div><button onClick={this.props.refresh}>Refresh</button><Bar queue={cache.queue} /></div>;
	}
}

此时点击Refresh按钮仍然没有反应......  

去掉对Foo的修饰,再尝试修饰一下Bar组件:

@observer
class Bar extends Component {
	static propTypes = {
		queue: PropTypes.array
		// queue: observablePropTypes.observableArray
	};
	render() {
		const queue = this.props.queue;
		return <span>{queue.length}</span>;
	}
} 

这时,按钮终于生效了!每点击一次数字就会增加1,React帮我们重新渲染组件了。

mobx能够精得知autorun依赖哪些可观察数据,做到按需触发,这两个组件虽然有上下级依赖关系,但Foo组件并没有使用到queue属性,而Bar组件用到了。

也就是说,谁真正用到了被修改到可观察数据,谁就会重新渲染,谁也就被observer修饰。

对没有使用任何可观察数据的组件,被修饰也没有什么副作用,因此,考虑到扩展性,建议修饰所有用到到组件。

React中的生命周期函数ShouldComponentUpdate()也可能会取消重新渲染,mobx-react也已经为React组件实现了一个ShouldComponentUpdate()方法,不再需要单独定义它,使得优化React应用程序更加的方便。

mobx-react只是mobx的一种应用场景,mobx并不局限于此。

posted @ 2019-12-26 17:26  阿江是个程序猿  阅读(744)  评论(0编辑  收藏  举报