demo功能很简单,效果及说明如下:
说明:
分析:
变量:firstName,lastName
方法:getFullName、doReset(为了方便,react还要封装一个setInputValue方法,让input监听onchange时调用)
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import registerServiceWorker from './registerServiceWorker';
class App extends Component {
constructor(props) {
super(props);
this.state = {
firstName: '',
lastName: ''
}
}
setValue(key, event) {
this.setState({
[key]: event.target.value
});
}
getFullName() {
let { firstName, lastName } = this.state;
if (!firstName && !lastName) {
return 'Please input your name!'
} else {
return firstName + ' ' + lastName;
}
}
doReset() {
this.setState({
firstName: '',
lastName: ''
})
}
render() {
const st = this.state;
const fullName = this.getFullName();
return (
This is normal react!
First name: this.setValue('firstName', e)} />
Last name: this.setValue('lastName', e)} />
Full name: {fullName}
);
}
}
ReactDOM.render( , document.getElementById('root'));
registerServiceWorker();
This is vue!
First name:
Last name:
Full name: {{fullName}}
对比:
区别还能说出来更多,但是最主要的就是这几点,那么当react遇到mobx时会发生什么呢?
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import registerServiceWorker from './registerServiceWorker';
import { observable, computed, useStrict, action } from 'mobx';
import { observer } from 'mobx-react';
useStrict(true)
class VM {
@observable firstName = '';
@observable lastName = '';
@computed get fullName() {
const { firstName, lastName } = this;
if (!firstName && !lastName) {
return 'Please input your name!'
} else {
return firstName + ' ' + lastName;
}
};
@action.bound
setValue(key, event) {
this[key] = event.target.value;
}
@action.bound
doReset() {
this.firstName = '';
this.lastName = '';
}
}
@observer
class App extends Component {
render() {
const vm = this.props.vm;
return (
This is mobx-react!
First name: vm.setValue('firstName', e)} />
Last name: vm.setValue('lastName', e)} />
Full name: {vm.fullName}
);
}
}
ReactDOM.render( , document.getElementById('root'));
registerServiceWorker();
那几个@xxxx虽然可能不太知道是啥意思,但是也差不多能猜出来八九不离十。仔细对比代码后可以发现:
vue作者尤雨溪如是说:
Mobx 在 React 社区很流行,实际上在 Vue 也采用了几乎相同的反应系统。在有限程度上,React + Mobx 也可以被认为是更繁琐的 Vue,所以如果你习惯组合使用它们,那么选择 Vue 会更合理。
结合react可以直接引用外部模块这点(通常是保存公共变量或方法的模块,这点vue需要靠vuex来实现,所以在这点上,react是更方便的),mobx可以替代redux作为项目的数据处理方案,可参考:【译】Redux 还是 Mobx,让我来解决你的困惑!
最后,如果有必要,再封装一些语法糖,甚至可以做到比vue还要简洁。当然,会额外增加学习成本,这个就需要自己权衡了。
最后附上用无状态组件实现的代码,大家可以品一下
父组件index
// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import registerServiceWorker from './registerServiceWorker';
import { App, AppVM } from './App';
ReactDOM.render( , document.getElementById('root'));
registerServiceWorker();
子组件App,无状态组件
// App.js
import React from 'react';
import { observer } from 'mobx-react';
import { observable, computed, action } from 'mobx';
export const App = observer(({ vm }) => (
This is mobx-react!
First name: vm.setValue('firstName', e)} />
Last name: vm.setValue('lastName', e)} />
Full name: {vm.fullName}
))
export class AppVM {
@observable firstName = '';
@observable lastName = '';
@computed get fullName() {
const { firstName, lastName } = this;
if (!firstName && !lastName) {
return 'Please input your name!'
} else {
return firstName + ' ' + lastName;
}
};
@action.bound
setValue(key, event) {
this[key] = event.target.value;
}
@action.bound
doReset() {
this.firstName = '';
this.lastName = '';
}
}
我故意把render放在了上面,怎么样,这么看是不是更像vue了点~