Redux学习(一)——Redux的使用过程
一、為什么需要redux
- JavaScript開發的應用程序,已經變得越來越復雜了:
是否顯示加載動效,當前分頁;
- 管理不斷變化的state是非常困難的:
- React是在視圖層幫助我們解決了DOM的渲染過程,但是State依然是留給我們自己來管理:
-
Redux就是一個幫助我們管理State的容器:Redux是JavaScript的狀態容器,提供了可預測的狀態管理;
-
Redux除了和React一起使用之外,它也可以和其他界面庫一起來使用(比如Vue),并且它非常小(包括依賴在內,只有2kb)
二、Redux的核心理念 - Store
Redux的核心理念非常簡單。
- 比如我們有一個朋友列表需要管理:
整個應用程序錯綜復雜,當出現bug時,很難跟蹤到底哪里發生的變化;
三、Redux的核心理念 - action
Redux要求我們通過action來更新數據:
- 所有數據的變化,必須通過派發(dispatch)action來更新;
- action是一個普通的JavaScript對象,用來描述這次更新的type和content;
比如下面就是幾個更新friends的action:
- 強制使用action的好處是可以清晰的知道數據到底發生了什么樣的變化,所有的數據變化都是可跟追、可預測的;
- 當然,目前我們的action是固定的對象,真實應用中,我們會通過函數來定義,返回一個action;
四、Redux的核心理念 - reducer
但是如何將state和action聯系在一起呢?答案就是reducer
- reducer是一個純函數;
- reducer做的事情就是將傳入的state和action結合起來生成一個新的state;
五、Redux的三大原則
- 整個應用程序的state被存儲在一顆object tree中,并且這個object tree只存儲在一個 store 中:
- Redux并沒有強制讓我們不能創建多個Store,但是那樣做并不利于數據的維護; p 單一的數據源可以讓整個應用程序的state變得方便維護、追蹤、修改;
- 唯一修改State的方法一定是觸發action,不要試圖在其他地方通過任何的方式來修改State:
- 這樣就確保了View或網絡請求都不能直接修改state,它們只能通過action來描述自己想要如何修改state;
- 這樣可以保證所有的修改都被集中化處理,并且按照嚴格的順序來執行,所以不需要擔心race condition(竟態)的問題;
- 通過reducer將 舊state和 actions聯系在一起,并且返回一個新的State:
- 隨著應用程序的復雜度增加,我們可以將reducer拆分成多個小的reducers,分別操作不同state tree的一部分;
- 但是所有的reducer都應該是純函數,不能產生任何的副作用;
六、Redux的使用過程
- 創建store時必須創建reducer;
- 我們可以通過 store.getState 來獲取當前的state
- 通過dispatch來派發action;
- 通常action中都會有type屬性,也可以攜帶其他的數據;
- 這里一定要記住,reducer是一個純函數,不需要直接修改state; - 后面我會講到直接修改state帶來的問題;
七、Redux結構劃分
如果我們將所有的邏輯代碼寫到一起,那么當redux變得復雜時代碼就難以維護。
接下來,我會對代碼進行拆分,將store、reducer、action、constants拆分成一個個文件。
注意:node中對ES6模塊化的支持
- 目前我使用的node版本是v14.16.1,從node v13.2.0開始,node才對ES6模塊化提供了支持:
- node v13.2.0之前,需要進行如下操作:
在package.json中添加屬性: “type”: “module”;
在執行命令中添加如下選項:node --experimental-modules src/index.js;
node v13.2.0之后,只需要進行如下操作:
在package.json中添加屬性: “type”: “module”;
注意:導入文件時,需要跟上.js后綴名;
index.js:
store/index.js:
store/actionCreator.js:
store/reducer.js:
store/constants.js:
八、Redux官方圖
九、redux融入react代碼
目前redux在react中使用是最多的,所以我們需要將之前編寫的redux代碼,融入到react當中去。
這里我創建了兩個組件:
核心代碼主要是兩個:
3. 在 componentDidMount 中定義數據的變化,當數據發生變化時重新設置 counter;
4. 在發生點擊事件時,調用store的dispatch來派發對應的action;
Home.js:
import React, {PureComponent} from 'react'; import store from "../store";import {addAction} from "../store/actionCreator";class Home extends PureComponent {constructor(props) {super(props);this.state = {counter: store.getState().counter}}componentDidMount() {this.unsubscribue = store.subscribe(() => {this.setState({counter: store.getState().counter})})}componentWillUnmount() {this.unsubscribue()}render() {return (<div><h1>Home</h1><h3>當前計數:{this.state.counter}</h3><button onClick={e => this.increment()}>+1</button><button onClick={e => this.addNumber(5)}>+5</button></div>);}increment () {store.dispatch(addAction(1))}addNumber (num) {store.dispatch(addAction(num))} }export default Home;About.js:
import React, {PureComponent} from 'react'; import store from "../store"; import {addAction, subAction} from "../store/actionCreator";class About extends PureComponent {constructor(props) {super(props);this.state = {counter: store.getState().counter}}componentDidMount() {this.unsubscribue = store.subscribe(() => {this.setState({counter: store.getState().counter})})}componentWillUnmount() {this.unsubscribue()}render() {return (<div><h1>About</h1><h3>當前計數:{this.state.counter}</h3><button onClick={e => this.subNumber(1)}>-1</button><button onClick={e => this.subNumber(5)}>-5</button></div>);}subNumber (num) {store.dispatch(subAction(num))} }export default About;App.js:
import React, {PureComponent} from 'react'; import Home from "./pages/Home"; import About from "./pages/About";class App extends PureComponent {render() {return (<div><Home/><hr/><About/></div>);} }export default App;總結
以上是生活随笔為你收集整理的Redux学习(一)——Redux的使用过程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: docker 虚拟机搭建mongodb一
- 下一篇: Web框架——Flask系列之CSRFT