Redux
1、基本用法:
-
Redux中存在幾個概念:state, action, dispatch
state: 依舊是組件的內(nèi)部的狀態(tài)
action: 組件動作,相應(yīng)的改變組件內(nèi)部的狀態(tài)值
dispatch: 發(fā)出相應(yīng)的動作Redux中提供createStore方法用于生成一個store對象,這個函數(shù)接受一個初始值state值和一個reducer函數(shù)。當(dāng)用戶發(fā)出相應(yīng)的action時,利用傳入的reducer函數(shù)計算出一個新的state值,并返回。
使用Redux,我們只獲取一次數(shù)據(jù)并將其存儲在一個中心位置,稱為 store。然后,任何組件都可以隨時使用這些數(shù)據(jù)。這就像附近有一家超市,我們的廚師可以在那里買到所有的食材。這家超市派卡車從農(nóng)場大批運回蔬菜和肉類。這比讓個別廚師親自去農(nóng)場效率高得多。
store 還是唯一的數(shù)據(jù)源。組件通常從
store中獲取數(shù)據(jù),而不是其他地方。這使得 UI 保持高度統(tǒng)一。store對象中包括getState方法(獲取目前的state),subscribe方法(指定監(jiān)聽函數(shù),當(dāng)state變化時調(diào)用),dispatch方法(分發(fā)action)。
在使用過程中,需要將store作為參數(shù)傳遞給子組件。
// reducer
function counter(state = 0, action) {
switch (action.type) {
case 'ADD':
return state + 1;
case 'SUB':
return state - 1;
default:
return 10;
}
}
// 創(chuàng)建Store
let store = createStore(counter);
console.log(store.getState()); // 10
// 監(jiān)聽器
function listener() {
console.log(store.getState()) // 先輸出11,在輸出10
}
// 訂閱事件監(jiān)聽
store.subscribe(listener);
// 分發(fā)事件
store.dispatch({ type: 'ADD' });
store.dispatch({ type: 'SUB' });
-
多個reducer
當(dāng)存在多個reducer,分別管理不同方面的state,需要將其合并成一個reducer,redux中提供了combineReducers函數(shù),完成該項功能。
combineReducers({ reducer1,reducer2 }) //返回合并后的reducer
2、redux的不足:
-
陡峭的學(xué)習(xí)曲線
Redux 的學(xué)習(xí)曲線比較陡峭。 理解,記憶并習(xí)慣其模式需要時間。 如果你完全不會 Redux 和 React ,不推薦你兩者同時學(xué)習(xí)。
-
“樣板” 代碼
在許多情況下,使用Redux意味著編寫更多代碼。通常需要接觸多個文件才能使一個簡單的功能正常工作。人們一直在抱怨他們必須用 Redux 編寫的樣板代碼。
我知道,這聽起來很矛盾。 我不是說 Redux 能夠用最少的代碼實現(xiàn)功能嗎? 這有點像使用洗碗機。 首先,你得花時間仔細地排列盤子。 在此之前,你將看到洗碗機的好處:節(jié)省實際清潔餐具的時間,消毒餐具等。你必須決定準備時間是否值得。
-
性能損耗
由于其強制執(zhí)行的限制,Redux 也可能對性能產(chǎn)生影響。 每當(dāng)數(shù)據(jù)發(fā)生變化時,它會增加一點開銷。 在大多數(shù)情況下,這不是什么大問題,而且放緩并不明顯。 仍然,當(dāng)存儲中存在大量數(shù)據(jù)并且當(dāng)數(shù)據(jù)頻繁改變時(例如,當(dāng)用戶在移動設(shè)備上快速鍵入時),UI 可能因此變得緩慢。
3、Redux 不只是為 React 而生
- 一個常見的誤解是 Redux 僅用于 React。 聽起來Redux在沒有React的情況下無法做任何事情。 事實上,正如我們之前所討論的,Redux在幾個重要方面補充了React。 React 是最最常見的 Redux 用例。
- 然而,事實上,Redux可以使用任何前端框架,如Angular、Ember.js 甚至jQuery 或者 普通的JavaScript。試著谷歌一下,你會發(fā)現(xiàn)這個,這個,這個甚至這個。Redux 的一般思想適用于任何地方
- 只要你明智地使用 Redux,你可以在很多情況下得到它的好處,而不僅僅是在React應(yīng)用中。
react-redux
- react-redux是為了方便開發(fā),提供了一個Provider組件,以及connect方法。Provider組件作為做上層組件,需要將store作為參數(shù)注入組件中,此后在子組件中都可以訪問到store這個對象;connect方法接受兩個參數(shù):mapStateToProps,actionCreators,并返回處理后的組件,其中mapStateToProps可以將對應(yīng)的state作為prop注入對應(yīng)的子組件,actionCreator可以將對應(yīng)的actioncreator作為prop注入對應(yīng)的子組件。
// 定義Connect,將對應(yīng)的數(shù)據(jù)注入
const mapStateToProps = (state) => {
return { num: state }// 必須返回一個對象
};
const actionCreator = { addAction, subAction, addActionAsync }
App = connect(mapStateToProps, actionCreator)(App)
- 裝飾器寫法:
@connect(
(state) => ({ num: state.counter }),
{ addAction, subAction, addActionAsync }
)
- 使用上述寫法,需要安裝babel插件babel-plugin-transform-decorators-legacy,并且在babelrc中添加相應(yīng)的配置
npm install --save-dev babel-plugin-transform-decorators-legacy
"plugins": [
"transform-decorators-legacy"
]
React-router
- react-router提供了web和Native兩個版本,當(dāng)在瀏覽器中使用時,需要安裝react-router-dom
npm install --save react-router-dom
-
react-router-dom中提供了BrowserRouter, Link, Route, Switch,Redirect。
其中:
1、 BrowserRouter包裹所有需要路由控制的內(nèi)容,在使用redux時,需要放置在Provider組件中;
2、 Link組件用于鏈接某個路徑下,用戶點擊跳轉(zhuǎn);3、 Route組件用于路由到這個組件;
4、Switch組件用于在內(nèi)部Route組件中選一個;5、 Redirect組件用于重定向到某個路徑下;
<Provider store={store}>
<BrowserRouter>
<Switch>
<Route path="/" exact component={Dashboard}></Route>
<Route path="/login" component={Auto}></Route>
<Route path="/dashboard" component={Dashboard}></Route>
<!-- <Redirect to="/dashboard"></Redirect> -->
<!-- <Link to="/dashboard"></Link> -->
</Switch>
</BrowserRouter>
</Provider>,