redux的竞品 ,
EventEmitter
http://www.runoob.com/nodejs/nodejs-event.html
mobx的官方网站
https://mobx.js.org/index.html
dva的官方网站
https://dvajs.com/guide/concepts.html#%E6%95%B0%E6%8D%AE%E6%B5%81%E5%90%91
mobx 5.9.4
23天前出版,2019-04-22日的23天前。
CDN
- https://unpkg.com/mobx/lib/mobx.umd.js
- https://cdnjs.cloudflare.com/ajax/libs/mobx/5.9.4/mobx.js
- https://cdnjs.com/libraries/mobx
mobx安装
MobX由Mendix,Coinbase,Facebook开源
npm i mobx mobx-react --save
npm install mobx-react --save
ESNext装饰器(可选)
CDN:
https://unpkg.com/mobx/lib/mobx.umd.js
https://cdnjs.com/libraries/mobx
介绍 反应式虚拟依赖状态图 mobx
MobX 是一个经过战火洗礼的库,它通过透明的函数响应式编程(transparently applying functional reactive programming - TFRP)使得状态管理变得简单和可扩展。MobX背后的哲学很简单:
任何源自应用状态的东西都应该自动地获得。
其中包括UI、数据序列化、服务器通讯,等等。
要想使用 @observable
装饰器,首先要确保 在你的编译器(babel 或者 typescript)中 装饰器是启用的
定义observable, observer 和 action
observable 美 [əbˈzɜ:rvəbl] 可观察的
observer 美 [əbˈzɜ:rvə(r)] 观察者
actions 活动
computed 美[‘kɒmpət] 计算属性
modify [ˈmɑ:dɪfaɪ] 修改,被修饰的
mobx的工作步骤
一,定义你的状态,并使其可观察
二,创建一个响应更改的视图
三,更改状态
https://egghead.io/courses/manage-complex-state-in-react-apps-with-mobx
视频第一课代码
const { observable } = mobx;
const { boserver } = mobxReact;
cosnt { Component } = React;
@observer class Counter extends Component {
@observable count = 0;
render() {
return (<div>
Counter: {this.count} <br/>
<button onClick={this.handleInc}> + </button>
<button onClick={this.handleDec}> - </button>
</div>)
}
handleInc = () => {
this.count++;
}
handleDec = () => {
this.count--;
}
}
ReactDom.render(
<Counter />,
document.getElementById('app')
);
const { observable } = mobx;
const { boserver } = mobxReact;
cosnt { Component } = React;
const appState = observable({
count: 0,
});
appState.increment = function () {
this.count++;
}
appState.decrement = function () {
this.count--;
}
@observer class Counter extends Component {
render() {
return (<div>
Counter: {this.props.store.count} <br/>
Counter: {appState.count} <br/>
<button onClick={this.handleInc}> + </button>
<button onClick={this.handleDec}> - </button>
</div>)
}
handleInc = () => {
this.props.store.increment();
appState.increment();
}
handleDec = () => {
this.props.store.decrement();
appState.decrement();
}
}
ReactDom.render(
<Counter store={appState} />,
document.getElementById('app')
);
视频第二课的代码
const { observable } = mobx;
const { boserver } = mobxReact;
cosnt { Component } = React;
const DevTools = mobxDevtools.default;
const appState = observable({
count: 0,
});
appState.increment = function () {
this.count++;
}
appState.decrement = function () {
this.count--;
}
@observer class Counter extends Component {
render() {
return (<div>
<DevTools />
Counter: {this.props.store.count} <br/>
Counter: {appState.count} <br/>
<button onClick={this.handleInc}> + </button>
<button onClick={this.handleDec}> - </button>
</div>)
}
handleInc = () => {
this.props.store.increment();
appState.increment();
}
handleDec = () => {
this.props.store.decrement();
appState.decrement();
}
}
ReactDom.render(
<Counter store={appState} />,
document.getElementById('app')
);
视频第三课的代码
const { observable, computed } = mobx;
const { observer } = mobxReact;
const { Component } = React;
const DevTools = mobxDevtools.default;
const t = new class Temperature {
@observable unit = 'C';
@observable temperatureCelsius = 25;
@computed get temperatureKelvin(){
console.log('calculating Kelvin');
return this.temperatureCelsius * (9/5) + 32
}
@computed get temperatureFahrenthit() {
console.log('calculating Fahrenheit');
return this.temperatureCelsius + 273.15
}
@computed get temperature {
console.log('calculating temperature')
switch(this.unit) {
case 'K': return this.temperatureKelvin + '°K';
case 'F': return this.temperatureFahrenthit + '°F';
case 'C': return this.temperatureCelsius + '°C';
defalut: ;
}
}
}
// t.unit = 'K';
// t.temperature
// 'calculating temperature'
// 'calculating Kelvin'
// '68°K'
// t.unit = 'F';
// t.temperature
// 'calculating temperature'
// 'calculating Fahrenheit'
// '293.15°F'
const App = observer(({temperature}) => (<div>
{temperature.temperature}
<DevTools />
</div>))
ReactDom.reder(
<App temperature={t} />,
document.getElementById('app')
)
视频第四课与第五课的代码,@active
const { observable, computed } = mobx;
const { observer } = mobxReact;
const { Component } = React;
const DevTools = mobxDevtools.default;
const t = new class Temperature {
/*
@observable unit = 'C';
@observable temperatureCelsius = 25;
*/
constructor() {
extendsObservable(this, {
unit: 'C',
temperatureCelsius: 25
})
}
@computed get temperatureKelvin(){
console.log('calculating Kelvin');
return this.temperatureCelsius * (9/5) + 32
}
@computed get temperatureFahrenthit() {
console.log('calculating Fahrenheit');
return this.temperatureCelsius + 273.15
}
@computed get temperature {
console.log('calculating temperature')
switch(this.unit) {
case 'K': return this.temperatureKelvin + '°K';
case 'F': return this.temperatureFahrenthit + '°F';
case 'C': return this.temperatureCelsius + '°C';
defalut: ;
}
}
@action setUnit(newUnit){
this.unit = newUnit;
}
@action setCelsius(newCelsius) {
this.temperatureCelsius = newCelsius;
}
}
const App = observer(({temperature}) => (<div>{temperature.temperature}<DevTools /></div>))
ReactDom.reder(
<App temperature={t} />,
document.getElementById('app')
)
const { observable, computed } = mobx;
const { observer } = mobxReact;
const { Component } = React;
const DevTools = mobxDevtools.default;
const t = observable({
unit: 'C',
temperatureCelsius: 25,
temperatureKelvin: function(){
console.log('calculating Kelvin');
return this.temperatureCelsius * (9/5) + 32
},
temperatureFahrenthit: function() {
console.log('calculating Fahrenheit');
return this.temperatureCelsius + 273.15
},
temperature: function() {
console.log('calculating temperature')
switch(this.unit) {
case 'K': return this.temperatureKelvin + '°K';
case 'F': return this.temperatureFahrenthit + '°F';
case 'C': return this.temperatureCelsius + '°C';
defalut: ;
}
}
});
// t.unit = 'K';
// t.temperature
// 'calculating temperature'
// 'calculating Kelvin'
// '68°K'
// t.unit = 'F';
// t.temperature
// 'calculating temperature'
// 'calculating Fahrenheit'
// '293.15°F'
const App = observer(({temperature}) => (<div>{temperature.temperature}<DevTools /></div>))
ReactDom.reder(
<App temperature={t} />,
document.getElementById('app')
)
const { observable, computed } = mobx;
const { observer } = mobxReact;
const { Component } = React;
const DevTools = mobxDevtools.default;
class Temperature {
id = Math.random();
@observable unit = 'C';
@observable temperatureCelsius = 25;
@computed get temperatureKelvin(){
console.log('calculating Kelvin');
return this.temperatureCelsius * (9/5) + 32
}
@computed get temperatureFahrenthit() {
console.log('calculating Fahrenheit');
return this.temperatureCelsius + 273.15
}
@computed get temperature {
console.log('calculating temperature')
switch(this.unit) {
case 'K': return this.temperatureKelvin + '°K';
case 'F': return this.temperatureFahrenthit + '°F';
case 'C': return this.temperatureCelsius + '°C';
defalut: ;
}
}
@action setUnit(newUnit){
this.unit = newUnit;
}
@action setCelsius(newCelsius) {
this.temperatureCelsius = newCelsius;
}
@action("Update temperature and unit")
setTemperatureOrUnit(temperature, unit){
this.setUnit(unit);
this.setsetCelsius(temperature);
}
}
/*
const temps = observable([]);
temps.push(new Temperature());
*/
const temps = observable(asMap({
"Amsterdam": new Temperature(),
"Rome": new Temperature()
}));
const App = observer(({temperature}) => (<div>
/*
{temperature.map(t => <div key={t.id}>{t.temperature}</div>)}
*/
{temperature.entries().map(([city, t])=>{
return <div key={t.id}>{city}: {t.temperature}</div>
})}
<DevTools /></div>))
ReactDom.reder(
<App temperature={temps} />,
document.getElementById('app')
)
/*
// temps[0].unit = 'K';
// temps.push(new Temperature());
// temps.splice(o, 1);
// temps[1] = new Temperature(); 此无效
// Array.isArray(temps); // false
// Array.isArray(temps.slice()); // true
// Array.isArray(temps.toJS()); // true
*/
// temps.get("Amsterdam").unit = 'K';
// temps.set("Tel Aviv", new Temperature());
const boxed = observable(42);
boxed.get(); // 42
boxed.set(52) // undefined
boxed.get(); // 52
视频第六课 observer
const { observable, computed } = mobx;
const { observer } = mobxReact;
const { Component } = React;
const DevTools = mobxDevtools.default;
class Temperature {
id = Math.random();
@observable unit = 'C';
@observable temperatureCelsius = 25;
@computed get temperatureKelvin(){
console.log('calculating Kelvin');
return this.temperatureCelsius * (9/5) + 32
}
@computed get temperatureFahrenthit() {
console.log('calculating Fahrenheit');
return this.temperatureCelsius + 273.15
}
@computed get temperature {
console.log('calculating temperature')
switch(this.unit) {
case 'K': return this.temperatureKelvin + '°K';
case 'F': return this.temperatureFahrenthit + '°F';
case 'C': return this.temperatureCelsius + '°C';
defalut: ;
}
}
@action setUnit(newUnit){
this.unit = newUnit;
}
@action setCelsius(newCelsius) {
this.temperatureCelsius = newCelsius;
}
@action("Update temperature and unit")
setTemperatureOrUnit(temperature, unit){
this.setUnit(unit);
this.setsetCelsius(temperature);
}
@action inc() {
this.setCelsius(this.temperatureCelsius + 1)
}
}
const temps = observable(asMap({
"Amsterdam": new Temperature(),
"Rome": new Temperature()
}));
const App = observer(({temperature}) => (<div>
{temperature.entries().map(([city, t])=>{
return <TView city={city} temperature={t} />
})}
@observer class TView extends Component {
render(){
const t = this.props.temperature;
const city = this.props.city;
return(<li onClick={this.onTemperatureClick}>{city}: {t.temperature}</li>)
}
@active onTemperatureClick(){ // 这里不能使用箭头函数
this.props.temperature.inc();
}
}
<DevTools /></div>))
ReactDom.reder(
<App temperature={temps} />,
document.getElementById('app')
)