blackLearning.github.io icon indicating copy to clipboard operation
blackLearning.github.io copied to clipboard

redux and mobx comparision

Open Fadingvision opened this issue 7 years ago • 0 comments

redux and mobx comparision

Redux依靠一个统一且不可变的数据存储来同步数据,并且更新那里的数据时会触发应用的更新渲染。 state的更新是以一种不可变的方式进行,它会发布一条明确的action消息,这个消息必须被reducer函数处理。 由于使用了这样明确的方式,很容易弄清楚一个action是如何影响程序的state。

MobX借助于函数式响应型模式,state被包装在了可观察对象里,并通过props传递。 通过将state标记为可观察的,即可在所有观察者之间保持state的同步性。

setState

  1. 许多组件之间需要共享状态进行通信。
  2. 一个组件需要改变另一个组件的状态。

state

redux是不可变的,有严格的更新逻辑. mobx是可变的,可以直接更新。

redux拥有时间旅行,更加可预测,使用纯函数,debug更容易。

Store

redux 是单一store,由reducer进行拆分逻辑。

mobx 可以是多store, 每个store掌管不同的逻辑,但组件间可以共享同一个store.

基本改变state的方法

redux

const initialState = {
  todos: [
    {
      title: '1'
    },
    {
      title: '2'
    }
  ]
};

// reducer
function users(state = initialState, action) {
  switch (action.type) {
  case 'USER_ADD':
    return { ...state, todos: [ ...state.todos, action.todo ] };
  default:
    return state;
  }
}

// action
const addTodo = function(todo) {
	return { type: 'ADD_TODO', todo: todo };
}

// app
this.props.addTodo(todo);

// connect
connect(
	({ todos }) => ({ todos }), // mapStateToProps,
	(addTodo) => { 				// mapActionCreators(如果你不指定这个参数,就会将dispatch传入Props,由你自己来决定dispatch哪个action)
		return {
			addTodo,
		}	
})(App);

mobx

mobx中没有reducer的概念,你甚至不需要action, 因为state是直接可以可变的。 (但为了一个清晰的数据流,符合flux哲学,还是推荐所有改变state的地方都使用action声明来改变)

// 在根文件中启用严格模式,如果没有通过action来改变state,就会报错
import { useStrict } from 'mobx';

useStrict(true);

redux中的一个普通的store基本是一个类。逻辑很像把angular的scope提取出来。


// store
class TodoStore {
	@observable todos = []; // 建立依赖数据

	@computed get count() {
		return this.todos.length;
	}

	@action addTodo(todo) {
		this.todos.push(todo)
	}

	addTodoToLocal() {
		reaction(
			() => this.todos,
			todos => localStorage.setItem('todos', JOSN.strigify(todos));
		)
	}
}

export default new TodoStore();

// app

可以通过mobx-react提供的provider和inject来将todoStore注入到组件中,
也可以直接引入使用.

 // 每个需要用响应数据的组件都需要使用mobx-react提供的observer装饰器, 它将mobx的响应数据和react相连接,用来确保每次render函数中的响应数据更新之后,都重新render视图。

@observer
class App {
	constructor() {
		this.todoStore = todoStore;
		this.todoStore.addTodo(todo); // 直接通过来新增一个todo来更新state,
		如果不是严格模式,你可以直接this.todoStore.todos.push(todo)来更新state
	}

	render() {
		// ...
	}
}

通过比较可以看到,mobx的样板代码要比redux少很多,写起来也更直接, mobx内部实现远远大于redux,使得它可以用更少的代码来实现一样的效果,你只需要改变数据,其余的事就交给组件自己渲染。

Fadingvision avatar Aug 14 '17 16:08 Fadingvision