Redux 拡張機能

redux 以外にも 2 種類のミドルウェア (Redux-thunk と Redux-saga) と共通コンポーネント (React-Redux) があり、redux を使用して問題を解決することもできますが、これらの種類を学習することで開発がより効率的になります。

1. Redux サンク

Redux-thunk は、Redux で最も一般的に使用されるプラグインです。このプラグインはいつ使用されますか? たとえば、アクションをディスパッチした後、レデューサーに到達する前に、いくつかの追加操作でミドルウェア (ミドルウェア) を使用する必要があります。実際には、ミドルウェアを使用してログを記録し、クラッシュ レポートを作成し、非同期インターフェイスまたはルートを呼び出すことができます。このミドルウェアは、Redux のディスパッチの拡張である Redux-thunk (もちろん他のものも使用できます) で拡張できます。

(1) インストール

npm install --save redux-thunk

(2) ケース - カウンタ [非同期累積]

1.index.jsで

// 引入createStore对象
import {
    
     createStore ,applyMiddleware,compose} from 'redux'
// 引入中间件redux-thunk
import thunk from "redux-thunk"

// 引入reducer
import reducer from './reducer'

// 利用compose创造一个增强函数
const composeEnhancers =   window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?
    window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
    
    }):compose

// 通过增强函数,把thunk引入进来
const enhancer = composeEnhancers(applyMiddleware(thunk))

// const store = createStore(
//     reducer,
//     window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
// );
const store = createStore(reducer,enhancer)
export default store;

2. type in action、actionTypes.jsの一元管理

export const ASYNC_ADD_NUM_FN = "asyncAddNumFn";
export const JIAN = "jian";

3. 統合管理アクション、actionCreator.js

import {
    
     ADD, JIAN, DEL_LIST_ITEM } from './actionTypes'
// 以异步累加举例
//export const asyncAddNumFn = (data) => {
    
    
//    return {
    
    
 //       type: 'ASYNC_ADD_NUM_FN', 
 //       value: data
 //   }
//}
// 以高阶函数的形式书写
export const asyncAddNumFn = (data) => {
    
    
    return (dispatch) => {
    
     
        setTimeout(() => dispatch({
    
     type: ASYNC_ADD_NUM_FN, value: data }), 2000)
    }
}
// 计数器的减法
export  const jianFnAction = () =>{
    
    
    return {
    
    
        type:JIAN
    }
}

4. reducer.js 内

import {
    
     JIAN,ASYNC_ADD_NUM_FN } from './actionTypes'

const initState={
    
    
    num:0
}
// 导出一个函数,用于返回state
export default (state = initState, action) => {
    
    
    let newState = JSON.parse(JSON.stringify(state));    // 对原本的state做一次深拷贝
    console.log(action);
    switch(action.type){
    
    
        case JIAN:
            newState.num -=1;
            return newState;
        case ASYNC_ADD_NUM_FN:
            newState.num +=action.value;
            return newState;
        default:
            break;
    }
    return newState;
}

5. ページ内

import React, {
    
     Component } from 'react'
import store from '../redux';
import {
    
     addFnAction, jianFnAction,asyncAddNumFn} from '../redux/actionCreator'

export default class Count1 extends Component {
    
    
    state = {
    
    
        num:0
    }
constructor(p){
    
    
    super(p)
    this.state={
    
    
        num:0
    }
    this.state = store.getState()

    store.subscribe(this.storeChange.bind(this))
    console.log("11",this.state);
}
storeChange(){
    
    
    this.setState(
        store.getState()
     )
}
    render() {
    
    
        return (
            <div>
                <Add/>
                {
    
    this.state.num}
                <Jian/>
            </div>
        )
    }
}

// 子组件1加
class Add extends Component {
    
    
    add=()=>{
    
    
        // console.log("jia ");
        // store.dispatch(addFnAction())
       // redux-thunk会自动注入dispatch给actionCreators
  store.dispatch(asyncAddNumFn(1))
    }
    render() {
    
    
        return (
            <div onClick={
    
    this.add.bind(this)}>1</div>
        )
    }
}

// 子组件2减
class Jian extends Component {
    
    
    jian=()=>{
    
    
        console.log("jian");
        store.dispatch(jianFnAction())
    }
    render() {
    
    
        return (
            <div onClick={
    
    this.jian.bind(this)}>1</div>
        )
    }
}

実行後、その効果がわかり、追加は非同期で実行されます。

6. 特記事項

次のコードを使用すると、ページ内でイベントをディスパッチするときにさらに面倒になるため、promise を設定する必要があります

export const asyncAddNumFn = (data) => {
    
    
     return {
    
    
         type: ASYNC_ADD_NUM_FN, 
         value: data
     }
 }

したがって、この setTimeout を actionCreator に転送します。上記のポイント 3 を参照してください。

二、Redux-saga

redux-saga は redux が非同期の問題を解決するためのミドルウェアです。redux-saga ES6 ベースのジェネレーター、github アドレス.

Saga の redux-saga/effects にはいくつかのキーワードがあります:
fork: 新しいプロセスまたはスレッドを作成し、リクエストを同時に送信します。
call: API リクエストを送信
put: 対応するディスパッチを送信し、対応するアクションをトリガーする
takeEvery: 対応するアクションを監視し、各ディスパッチがトリガーする
takeLatest: 対応するアクションを監視し、最後のディスパッチのみをトリガーする
all: fork と同じ、同時複数アクション、注文なし。

redux-thunk と redux-saga はほぼ同じ機能を持っているので、redux-saga は generator をベースにする必要があり、書くのはより複雑です. ここでは概念の普及にすぎません. 興味のある方は参照してください.自分で学ぶためのドキュメント。

三、React-Redux

React-Redux React エコシステムの共通コンポーネントで、Redux プロセスを簡素化できます。実際には Redux の簡易版です。

(1) インストール

npm install --save react-redux
npm install --save redux

(2) プロバイダーとコネクター

1.プロバイダープロバイダー

これはプロバイダです. このコンポーネントが使用されている限り, コンポーネント内の他のすべてのコンポーネントはストアを使用できます. これはReact-reduxのコアコ​​ンポーネントでもあります. 簡単に言うと、store に配置されたすべてのコンポーネントは、 store 内のデータを取得できます通常、プロバイダはルート コンポーネントに直接記述されます

2. コネクタを接続します

データを取得するには、コンポーネントでコネクタを使用して反応に接続する必要があります

(3) ケース - カウンター

1.index.jsで

// 引入createStore对象
import {
    
     createStore} from 'redux'
// 引入reducer
import reducer from './reducer'

const store = createStore(reducer);
export default store;

2. reducer.js 内

const initState={
    
    
    num:0
}
// 导出一个函数,用于返回state
export default (state = initState, action) => {
    
    
    let newState = JSON.parse(JSON.stringify(state));    // 对原本的state做一次深拷贝
    switch(action.type){
    
    
        case "add_count":
            newState.num +=action.value;
            return newState;
        default:
            break;
    }
    return newState;
}

3. entry 関数内の index.js

プロバイダーでラップしてストアを提供する

import React from 'react';
import ReactDOM from 'react-dom/client';
import ReactRedux from './view/ReactRedux'
import {
    
     Provider } from 'react-redux'
import store from './redux/index'

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <Provider store={
    
    store}>
       <ReactRedux />
    </Provider>
  </React.StrictMode>
);

4. ページ

接続リンクを通じて、2 つのマッピングが導入され、ストアの導入が削除され、コネクタとマッピングの関係が追加されます。

import React from 'react'
import {
    
    connect} from 'react-redux'  //引入连接器

function ReactRedux(props) {
    
    
  return (
    <div>
        <h2>{
    
    props.num}</h2>
        <button onClick={
    
    props.addFn}>增加</button>
    </div>
  )
}
// stateToProps是一种映射关系,把原来的state映射成组件中的props属性
const stateToProps = (state)=>{
    
    
    return {
    
    
        num : state.num
    }
}
// dispatchToPros也是一种映射,用于传递并修改数据,这里要返回一个对象并包含一个事件
const dispatchToPros = (dispatch)=>{
    
    
    return {
    
    
        addFn(){
    
    
            dispatch({
    
    
                type:"add_count",
                value:1
            })
        }
    }
}
export default connect(stateToProps,dispatchToPros)(ReactRedux);

(4) redux と react-redux の違い

1. コンセプト

Redux は、react (react プラグインではない) で状態を管理するための JS ライブラリであり、通常、複数のコンポーネントで共有データの状態を管理します。これは Vuex と同じです。
React-Redux は Redux の公式 React バインディング ライブラリです。これにより、React コンポーネントが Redux ストアからデータを読み取り、アクションをストアにディスパッチしてデータを更新できるようになります。

2.使用

redux とコンポーネントが接続されると、それらはコンポーネント内に直接作成されます。ここに画像の説明を挿入

react-redux は Provider を使用してコンポーネントをストアに接続し、Provider 内のすべてのコンポーネントがストア内のデータを共有し、コンポーネントを接続して反応できるようにします。
ここに画像の説明を挿入
ここに画像の説明を挿入

3. 状態の取得方法が異なる

Redux は、store.getState() を介して直接状態を取得します。
ここに画像の説明を挿入
react-redux は mapStateToProps 関数を介して状態を取得します。状態データが変化する限り、最新のデータを取得できます。
ここに画像の説明を挿入

4. アクションのトリガー方法が異なる

Redux はディスパッチを使用して直接トリガーし、ストア データを操作します。
ここに画像の説明を挿入

react-redux は mapDispathToProps 関数を使用し、ディスパッチを呼び出してトリガーします
ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/m0_55173487/article/details/128853711