mobx 学习笔记

2019-10-14  本文已影响0人  不决书

mobx vs redux

mobx的核心思路

状态变化引起副作用应该被触发

Action ---> State ---> Reaction

什么是observable

import  { observable,isArrayLike } from 'mobx'

//observable.box

//array object map

//array
const arr= observable(['a','b','c']);

console.log(arr)  //ObservableArray{$mobx:ObservableArrayAdministration}

console.log(Array.isArray(arr)) //false

console.log(isArrayLike(arr))  //true

//包含了数组的所有原有方法, `arr[3]`数据越界会失去observable的相应
//对象
//可以按照访问到对象的所有属性
const obj = observable({a:1,b:2});

console.log(obj)   // {$mobx:ObservableArrayAdministration}


//map

//包含map的所有属性
const map = observable(new Map());
  map.set('a',1);

console.log(map) //ObservableMap {...}

//原始数据类型需要包装

var num = observable.box(20);
var str  = observable.box('hello');
var bool = observable.box(true);
//使用get 方法可以得到原来的值,使用set设置值
num.get();
num.set(111);
console.log(num,str,bool) //ObservleValue{...}

装饰器的编写

import  { observable,isArrayLike} from 'mobx'

class Store{
  @observable  array = [];
  @observabel obj=[];
  @observable map = new Map();

  @observable str = 'hello';
  @observable  number = 123;
 @observable boo= true
}

如何对可观察的数据做出反应

import  { observable,isArrayLike,computed,autorun ,when, reaction,action,runInAction} from 'mobx'

class Store{
  @observable  array = [];
  @observabel obj=[];
  @observable map = new Map();

  @observable string = 'hello';
  @observable  number = 123;
  @observable boo= true;

@computed get mixed(){
  return store.string + '/' + store.number;
}
 @action.bound bar(){
      this.string ='world';
      this.number = 30;
}
 
}

//computed 可以将多个可观察数据变成一个可观察数据
const store = new Store();
//let foo = computed(function(){ return store.string + '/' + strore.number});

//console.log(foo)   //ComputedValue {...}
//获取计算的结果
//console.log(foo.get())   //hello/123 

//foo.observe(function(change){
    // {type:'update',object:ComputeValue,newValue:'world/20',oldValue:'hello/20'}
    //{type:'update',object:ComputeValue,newValue:'world/30',oldValue:'world/20'}
//    console.log(change);
//})

//store.string = 'world' ;
//store.number = 30;

//autorun  自动追踪可观察数据,并在数据变化时重新触发

//autorun(()=>{
  //console.log(store.string + '/' + strore.number)
//  console.log(store.mixed);
//})

//store.string = 'world' ;
//store.number = 30;

//when  条件方式触发 
//第一个参数必须是bool类型,第一个参数为true, 第二个参数立即执行
//when(()=>store.bool,()=>console.log(''it's true));

//store.bool= true  //when 返回 'it's true

//reaction 分离可观察数据的申明,以副作用的方式对autorun 改进

reaction(()=>[store.string,store.number],arr=>console.log(arr.join('/')))

/*runInAction(()=>{
  store.string = 'world' ;
  store.number = 30;
})*/

runInAction('modify',()=>{
  store.string = 'world' ;
  store.number = 30;
})

var bar = store.bar();

bar();
//store.string = 'world' ;
//store.number = 30;

mobx-react

npm i react react-dom prop-types mobx-react -S

//index.jsx
import {observable , action } from 'mobx'
import React , { Component } from 'react';
import ReactDOM from 'react-dom'
import PropTypes from 'prop-types';
import {observer, PropTypes as ObservableProptyps}  from 'mobx-react';

class Store{
  @observable  cache = {queue: [] }
  @action.bound refresh(){
      this.cache.queue.push(1);
  }
}

@ observer
class Bar extends Component{
    static propTypes={
          queue: ObservablePropTypes.observableArray
    };
  
   render(){
        const queue = this.props.queue;

        return <span>{queue.length}</span>;
  }
  
}

@ observer
class  Foo extends Component{
      static propTypes={
                cache:ObservablePropTypes.obvervableObject
      };
    
    render(){
            const cache  = this.props.cache;

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

}

ReactDom.render(<Foo cache={store.cache}/>,document.getElementById('root'))

运行前,按照 npm i babel-preset-react -D

<!--index.html-->
  
  <div id="root"></div>

实现TODOList

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

class Todo{
    id= Math.random();
    @observable title= '';
    @observable finished = false;  
  
     constructor(title){
          this.title = title;
    }

  @action.bound toggle(){
          this.finished= ! this.finished;
  }
}

class Store = {
    @observable  todos: [];
    
     @action.bound createTodo(title){
           this.todos.unshift( new Todo(title) )
     } 

    @computed get left(){
        return this.todos.filter(todo=>!todo.finished).length;
    }

}

var store = new Store();

@observer
class TodoItem extends Component {
          static propTypes = {
            todo:PropTypes.shape({
                    id: PropTypes.number.isRequired,
                    title:PropTypes.string.isRequired,
                    finisthed:PropTypes.bool.isRequired
            }).isRequired
          }
         handleClick=()=>{
                this.props.todo.toggle()
        }
        render(){
                const todo = this.props.todos;
                return (
                      <Fragment>
                    <input type="checkbox"   className="toggle"  checked={todo.finished} onClick={this.handleClick}/ >
                  <span class="title">{todo.title}</span>
                  <Fragment>
              )
        }

}

@observer
class TodoList extends Component {
        static  propTypes = {
          createTodo:PropTypes.func,
          store:PropsTypes.shape({
                  todos:  ObservablePropTypes.observableArrayOf(ObservablePropTypes.observableObject).isRequired
          }).isRequired
        };
       handleSubmit = (e)=>{
            e.preventDefault();

            const store= this.props.store;
            let inputValue  = this.props.inputValue;
            
            this.setState({
                inputValue:''
            })  
          
       }
       handleChange = (e)=>{
            let inputValue = e.target.value;
            this.setState({
                    inputValue  
          })
        }
        render(){
              const store = this.props.store;
              const todos = store.todos;
              return (
                  <div className="todo-list">
                  <header>
                  <form onSubmit={this.handleSubmit}>
                        <input type="text"  onChange={this.handleChange}  value={this.state.inputValue}  className="input"  placeholder="what needs to be finish"/>
                  </form>  
                  </header>
                   <ul>
                    {todos.map(todo=>{
                          return <li className="todo-item" key={todo.id}>         <TodoItem todo={todo}/>
                        </li>
                     })}
                    </ul>
                    <footer>{store.left} item(s) unfinished</footer> 
                </div>
          ) 
         }
}


ReactDom.render(<TodoList  store ={store}/>,document.querySelector('#root');

提升性能

三大法则

  1. 细粒度的拆分视图组件

2.使用专用组件处理列表

3.尽快能晚的解构可观察数据

mobx 的使用方法

mobx-react

提升开发体验,优化渲染性能

上一篇 下一篇

猜你喜欢

热点阅读