日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Redux学习(一)——Redux的使用过程

發布時間:2024/7/5 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Redux学习(一)——Redux的使用过程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、為什么需要redux

  • JavaScript開發的應用程序,已經變得越來越復雜了:
  • JavaScript需要管理的狀態越來越多,越來越復雜;
  • 這些狀態包括服務器返回的數據、緩存數據、用戶操作產生的數據等等,也包括一些UI的狀態,比如某些元素是否被選中,
    是否顯示加載動效,當前分頁;
    • 管理不斷變化的state是非常困難的:
  • 狀態之間相互會存在依賴,一個狀態的變化會引起另一個狀態的變化,View頁面也有可能會引起狀態的變化;
  • 當應用程序復雜時,state在什么時候,因為什么原因而發生了變化,發生了怎么樣的變化,會變得非常難以控制和追蹤;
    • React是在視圖層幫助我們解決了DOM的渲染過程,但是State依然是留給我們自己來管理:
  • 無論是組件定義自己的state,還是組件之間的通信通過props進行傳遞;也包括通過Context進行數據之間的共享;
  • React主要負責幫助我們管理視圖,state如何維護最終還是我們自己來決定;
    • Redux就是一個幫助我們管理State的容器:Redux是JavaScript的狀態容器,提供了可預測的狀態管理;

    • Redux除了和React一起使用之外,它也可以和其他界面庫一起來使用(比如Vue),并且它非常小(包括依賴在內,只有2kb)

    二、Redux的核心理念 - Store

    Redux的核心理念非常簡單。

    • 比如我們有一個朋友列表需要管理:
  • 如果我們沒有定義統一的規范來操作這段數據,那么整個數據的變化就是無法跟蹤的;
  • 比如頁面的某處通過products.push的方式增加了一條數據;
  • 比如另一個頁面通過products[0].age = 25修改了一條數據;
  • 整個應用程序錯綜復雜,當出現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是只讀的
    • 唯一修改State的方法一定是觸發action,不要試圖在其他地方通過任何的方式來修改State:
    • 這樣就確保了View或網絡請求都不能直接修改state,它們只能通過action來描述自己想要如何修改state;
    • 這樣可以保證所有的修改都被集中化處理,并且按照嚴格的順序來執行,所以不需要擔心race condition(竟態)的問題;
  • 使用純函數來執行修改
    • 通過reducer將 舊state和 actions聯系在一起,并且返回一個新的State:
    • 隨著應用程序的復雜度增加,我們可以將reducer拆分成多個小的reducers,分別操作不同state tree的一部分;
    • 但是所有的reducer都應該是純函數,不能產生任何的副作用;

    六、Redux的使用過程

  • 創建一個對象,作為我們要保存的狀態:
  • 創建Store來存儲這個state
    • 創建store時必須創建reducer;
    • 我們可以通過 store.getState 來獲取當前的state
  • 通過action來修改state
    • 通過dispatch來派發action;
    • 通常action中都會有type屬性,也可以攜帶其他的數據;
  • 修改reducer中的處理代碼
    • 這里一定要記住,reducer是一個純函數,不需要直接修改state; - 后面我會講到直接修改state帶來的問題;
  • 可以在派發action之前,監聽store的變化:
  • const redux = require('redux') const initalState = {counter: 0 } // reducer function reducer(state = initalState, action) {switch (action.type) {case 'INCREMENT':return {...state, counter: state.counter + 1}case 'DECREMENT':return {...state, counter: state.counter - 1}case 'ADD_NUMBER':return {...state, counter: state.counter + action.num}case 'SUB_NUMBER':return {...state, counter: state.counter - action.num}default:return state} }// store const store = redux.createStore(reducer)// 訂閱store的修改 store.subscribe(() => {console.log('counter: ', store.getState().counter) })// action const action1 = {type: 'INCREMENT'} const action2 = {type: 'DECREMENT'} const action3 = {type: 'ADD_NUMBER', num: 5} const action4 = {type: 'SUB_NUMBER', num: 12}// 派發action store.dispatch(action1) store.dispatch(action2) store.dispatch(action3) store.dispatch(action4)

    七、Redux結構劃分

    如果我們將所有的邏輯代碼寫到一起,那么當redux變得復雜時代碼就難以維護。

    接下來,我會對代碼進行拆分,將store、reducer、action、constants拆分成一個個文件。

  • 創建store/index.js文件:
  • 創建store/reducer.js文件:
  • 創建store/actionCreators.js文件:
  • 創建store/constants.js文件:
  • 注意: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當中去。
    這里我創建了兩個組件:

  • Home組件:其中會展示當前的counter值,并且有一個+1和+5的按鈕;
  • About組件:其中會展示當前的counter值,并且有一個-1和-5的按鈕;

  • 核心代碼主要是兩個:
    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的使用过程的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。