Remux - Redux多實例的解決方案

背景

目前,在 react 的數據狀態管理領域最有影響力有兩大流派:javascript

  • 一類是以函數式編程爲表明的 redux,特色是經過單 store 與約定狀態爲不可變數據結構,使得狀態易追蹤與回溯,可預期。
  • 一類是以響應式編程爲表明的 mobx,特色是容許對狀態進行直接修改,經過 observable 對 view 進行更新。

問題

以redux爲例,從目前現狀來看,redux 單一數據源帶來了自然數據收集和管理的優點,但開發的時候,咱們煩擾於java

  • redux 過多的代碼模版(固然,社區也出現了不少優秀的去形式化,簡化代碼的庫如:dva iron-redux
  • 單store 在跨項目複用存在難抽離及注入新項目須要根據項目進行改造代碼風格。
  • store 的生命週期不必定是和 view 生命週期對應,缺乏生命週期管理。
  • 單store 的按需加載和卸載,每一次都須要從新合併 reducer ,從新調用 replaceReducer 全局刷一遍。(參考dva)
  • 想使用 hooks ,又捨不得 redux 繁榮的社區,還不想要影響到當前已經穩定的項目。

咱們真正須要的點

  • 保留目前單 store 和中間件的優點。
  • 解決多項目複用問題和代碼模版過多問題。
  • model 層的生命週期管理。
  • 擁有按需加載的能力及良好的掛載性能。
  • 接軌 redux 社區生態和使用習慣。
  • 學習心智成本低,使用方便。
  • 提供簡單又強大的 hooks

什麼是 remux

remux 是基於 redux 包裝,可插拔式狀態管理,漸進式式開發的多 store 實例的框架。react

它提供如下能力:git

  • 中心化數據的能力(保留單 store 方便處理數據源的優點)。
  • 動態掛載局部數據到全局的能力。(這裏是多 store 實例的掛載,而非單 store 實例的 inject)
  • 擁有類 dva 的最佳實踐範式約束。
  • model 的生命週期管理,能夠用於和 view 層關聯。
  • 強大的插件機制、豐富的插件生態(能夠直接複用 redux 插件生態)。
  • 和現有的 Redux devtools 進行無縫結合,進行調試和狀態回放操做。
  • 提供簡單又強大的 hooks

remux 的設計理念:

  1. 分佈式掛載,中心式管理 - 以 namespace 爲命名空間,每一個 store 實例本身處理掛載,註銷,以及數據管理,統一掛載在 store manager 上。
  2. store即沙箱 - store 做爲沙箱,state,plugin,middlware自然隔離,隔離內部的業務邏輯。
  3. 按需獲取store - 經過 store manager 不只能夠得到本身 store 裏的數據,也有能力得到別的 store 的數據。
  4. 豐富的中間件機制 - 提供更加豐富的中間件機制,來對 remux 進行加強,也能夠直接複用 redux 中間件生態。
  5. 內置中間件簡化流程 - 簡化代碼 默認支持異步(基於redux-saga)、hooksloading態dispatch 默認返回 promise

快速開始

  1. 首先定義一個store的 json scheme
export default {
    namespace:"app",
    state: {
        count: 0
    },
    reducers: {
        increment(state) {
			return{
			 count: state.count+1
			} 
        }
    },
  effects:{
	   async asyncIncrement(state, { dispatch }) {
			function delay(timeout) {
			  return new Promise(resolve => setTimeout(resolve, timeout));
			}
			await delay(1000);
			dispatch({
			  type: "increment"
			});
		}
  }
}
複製代碼
  1. 建立 store 的實例
import { Provider } from 'react-remux';
export default ()=>{
  return <Provider model={model}><App/></Provider>
}
複製代碼
  1. 與 view 綁定,並在組件中使用
  • class component
import {connect} from 'react-remux';
@connect(state=>state.app);
class App extends React.Component {
    render() {
        const { count ,dispatch  } = this.props
		// 常規寫法
        const onClickHandler = ()=>dispatch({type:'app/increment'}})
		// 簡寫
        const onClickHandler = ()=>dispatch({type:'increment'}})
		// 直接不寫type
        const onClickHandler = ()=>dispatch({count:count+1}})
        return <div> <button onClick={onClickHandler}>add</button> <span>{count}</span> </div>
    }
}
複製代碼
  • function component
import {
  useSelector,
  useDispatch,
  shallowEqual
} from 'react-remux';
const App = ()=>{
		const dispatch = useDispatch()
		const state = useSelector((store: any) =>store.app, shallowEqual);
		// 常規寫法
        const onClickHandler = ()=>dispatch({type:'app/increment'}})
		// 簡寫
        const onClickHandler = ()=>dispatch({type:'increment'}})
		// 直接不寫type
        const onClickHandler = ()=>dispatch({count:state.count+1}})
        return <div> <button onClick={onClickHandler}>add</button> <span>{count}</span> </div>
    
}
複製代碼

想了解更多,請跳轉github

完整的示例請參考:
Todos App
Guide
remux-fractal編程

多store的數據流

咱們對比一下 redux 數據流和 remux 數據流的區別:json

redux 數據流redux

redux 數據流
remux 數據流

remux 數據流

最後

remux 站在巨人的肩膀上借鑑了 redux 和 dva 的一些優秀設計理念,例如單向數據流狀態可追蹤,中間件機制,redux-saga的集成,內置的 loaidng、promise,而且針對使用 redux 中的一些痛點做了再設計,使其易上手、易調試、可擴展。promise

最後若是在使用過程當中遇到任何問題或者有功能建議歡迎經過 issue 反饋給咱們,很是感謝。數據結構

相關文章
相關標籤/搜索