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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

rematch:当你受不了redux繁琐写法的时候,是时候了解一波rematch了

發布時間:2023/12/13 综合教程 39 生活家
生活随笔 收集整理的這篇文章主要介紹了 rematch:当你受不了redux繁琐写法的时候,是时候了解一波rematch了 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言:

前段時間學習完react后,剛好就接到公司一個react項目的迭代,順便鞏固一下前段時間的學習成果。項目使用的是redux+react-router,將所有的數據都放在redux中,異步處理數據使用redux-saga。由于是迭代項目,所以代碼風格還是沿用之前項目的寫法,將所有的數據都放在redux中。寫redux的時候心中默默的吐槽了無數次,特別是每次從服務端異步獲取數據的時候心中都會默默的想 “我只是想實現從服務端取一個列表數據,然后保存在store中,為什么需要引入redux-saga,并且引入后寫法還是很繁瑣(雖然流程很清晰明了,但是需要進行大量的復制粘貼)” ,寫著寫著感覺心態就快崩了 。后面經過同事的介紹,了解到有rematch這么一個更好用的js狀態容器,終于可以脫離redux了。

簡介:

先看看rematch的官方介紹:

Rematch是沒有boilerplate的Redux最佳實踐。沒有多余的action types,action creators,switch 語句或者thunks。

rematch是在redux的基礎上再次封裝后成果,在rematch中我們不用聲明action類型、action創建函數、thuks、store配置、mapDispatchToProps、saga。如果你習慣使用vuex,那么你一定會喜歡上rematch的,因為rematch的寫法和vuex基本一樣。

一個簡單的demo:

先看看我們的項目結構:

├── index.html
├── index.js          # 項目的入口
├── ....
└── store
    ├── index.js           # 引入modules的各個模塊,初始化store的地方
    └── modules
        ├── count.js       # count模塊
        └── info.js      # info模塊

1. store/index.js,初始化一個store實例

import { init } from '@rematch/core';
import count from './modules/count';
import info from './modules/info';

const store = init({
    models: {
        count,
        info,
    }
})

export default store;

  rematch提供 init()方法,返回一個store的實例。初始化store的時候rematch支持傳入多個模塊,在中、大型項目中可以根據業務的需要,拆分成多個模塊,這樣項目的結果就會變得清晰明了。

2. store/modules/count.js,編寫count模塊業務代碼

const count = {
    state: {
        num: 1,
     type: 2 }, reducers: { increment(state, num1, num2) { // 從第二個變量開始為調用increment時傳遞進來的參數,后面依次類推,例如:dispatch.count.increment(10, 20)時, num1 = 10 , num2 = 20. return {
          ...state, num: num1 } }, }, effects: { async incrementAsync(num1, rootState, num2) { // 第二個變量為當前model的state的值,num1為調用incrementAsync時傳遞進來的第一個參數,num2為調用時傳遞的第二個參數,后面依次類推。例如:dispatch.count.incrementAsync(10, 20)時,num1 = 10, num2 = 20 await new Promise(resolve => setTimeout(resolve, 2000)); this.increment(num1); } } } export default count;

  事實上我們的count模塊就是一個對象,該對象包含三個屬性:state、reducers、effects。

  state:存放模塊狀態的地方。

  reducers:改變store狀態的地方,每個reducers函數都會返回一個對象作為模塊最新的state。reducers中的函數必須為同步函數,如果要異步處理數據需要在effects中處理。注意:只能通過在reducers的函數中通過返回一個新的對象來改變模塊中state的值,直接通過修改state的方式是是不能改變模塊的state的值。例:

        increment(state, num1) {  
            state.num = num1  // 這樣的寫法是錯誤的
        },

  effects:處理異步數據的地方,比如:異步從服務端獲取數據。注意:在effects中是不能修改模塊的state,需要在異步處理完數據后調用reducers中的函數修改模塊的state。

  rematch的state、reducers、effects和vuex的state、mutaition、action用法非常相似,在vuex中mutation修改model的state的值,action進行異步處理數據。

3. 在組件中獲取state和修改state的值

  有2種方法可以獲取state和修改state:(1)使用redux的高階組件connect將state、reducers、effects綁定到組件的props上。(2)使用rematch提供的dispatch和getState。

  (1)使用redux的高階組件connect

    使用redux提供的高階組件connect給App組件注冊countState和countDispatch屬性,其中countState對應的是count模塊的state屬性,countDispatch對應的是count模塊的reducers和effects。在組件中使用this.props.countState和this.props.countDispatch就可以訪問到count模塊提供的state和reducers、effects了。

import React, {Component} from 'react';
import {connect} from 'react-redux';

class App extends Component {
    handleClick = () => {
      const { countDispatch } = this.props;
        countDispatch.increment(10)
    };

    render() {
        const { countState } = this.props;
        return (
            <div className="App" onClick={this.handleClick}>
                當前num為{countState.num},點我num加10
            </div>
        );
    };
}

const mapStateToProps = (state) => ({
    countState: state.count
})

const mapDispatchToProps = (dispatch) => ({
    countDispatch: dispatch.count
})

export default connect(mapStateToProps, mapDispatchToProps)(App);

  (2)dispatch和getState

    getState:rematch提供的getState方法返回整個store的state對象,如果要單獨訪問count模塊的state,只需要 getState( ).count即可。

    dispatch:rematch提供的dispatch可以直接調用整個store中定義的reducers和effects。例:dispatch.count.increment(10) ,其中count為store中的一個model,increment方法為count模塊中提供的一個reducers。調用effects的方法和調用reducers的方法一樣。

import React, {Component} from 'react';
import { dispatch, getState } from '@rematch/core';

class App extends Component {
    handleClick = () => {
     console.log(getState().count); // {num: 1, a: 1} dispatch.count.increment(10) }; render() { let countState = getState().count; console.log(countState); return ( <div className="App" onClick={this.handleClick}> 當前num為{countState.num},點我num加10 </div> ); }; }
const mapStateToProps = (state) => ({
    countState: state.count
})

const mapDispatchToProps = (dispatch) => ({
    countDispatch: dispatch.count
})

export default connect(mapStateToProps, mapDispatchToProps)(App);

    

4、在一個model的reducers中的函數中觸發另外一個model的reducers中的函數  

  場景:A函數和B函數里面有大量相似的代碼,這個時候我們一般的做法都是將A、B函數的公共部分提取出來成一個公共函數,這樣我們就不需要在A函數和B函數中寫大量相似的代碼。假如在reducers中,我們將A函數和B函數提取的公共函數C放在公共模塊info的reducers中,A函數是在count模塊的reducers中。在這種情況下我們就需要在公共模塊info的函數C執行完后調用count模塊的A函數。

{  // count模塊
    ...
    reducers: {
        ...
        'info/addAge': (state, payload) => {  // payLoad的值為addAge傳入的值10
            console.log(payload)  // 10
            return {
                ...state,
                num: 10
            }
        }
    },
    ...
}

{  // info模塊
    ...
    reducers: {
        addAge(state, num) {
            return {
                age: state.age + num.age,
            }
        }
    }
    ...
}

  通過dispatch.info.addAge(10)調用info模塊的addAge函數,當addAge函數執行完后會觸發count模塊的 ' info/addAge ' ,并且' info/addAge '的參數payload的值為調用info模塊的addAge函數時傳入的參數 10

總結:

由于rematch的寫法和vuex很相似,所以在接觸rematch的時候覺得非常熟悉,很好上手,具體有有哪些坑只有等下次項目中引入了rematch踩了才知道。

總結

以上是生活随笔為你收集整理的rematch:当你受不了redux繁琐写法的时候,是时候了解一波rematch了的全部內容,希望文章能夠幫你解決所遇到的問題。

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