わかりやすいreact-reduxチュートリアル

29036 ワード

前言
reduxコアは簡単です.
redux
reduxコア
reduxは簡単で、まとめるとイベント通知付きのステータス保存者です.コードを見て、中の下のコードが分かったら、直接プラグインにジャンプします.
const {createStore} = require('redux');

function reducer(state, action) {
    switch (action.type) {
        case 'add':
            return {value: state.value + action.payload}
        case 'dec':
            return {value: state.value - action.payload}
        default:
            return state
    }
}

const store = createStore(reducer, {value: 1})
const subscriber = () => {
    console.log("     ", store.getState())
};
store.subscribe(subscriber)
store.dispatch({type: 'add', payload: 2})
store.dispatch({type: 'dec', payload: 1})

実行結果
      { value: 3 }
      { value: 2 }

コードは極めて簡単ですが、reduxのすべてのコア(すべて)の内容もここにあります.ステータスを保存するためにstoreを作成するcreateStore関数は1つだけで、入力されたパラメータは1~3つです.最初のパラメータはreducer関数と呼ばれ、作用は生成状態であり、各2つのパラメータは初期状態であり、3番目のパラメータがあればプラグインである.最初のパラメータのみが必要です.
storeオブジェクト
3つの方法で
  • getState()は、ステータス
  • を取得するために使用されます.
  • dispatch(action)は、storeにオブジェクトであればいいと伝え、オブジェクトフォーマットは要求されず、reducerが認識すればいいと伝えた.ほとんどは公式サイトの書き方で、{type:‘someKey’,payload:‘someValue’}と書かれ、イベント名を表し、パラメータ
  • subscriber(callback)は、状態が変化した後、callbackに通知します.この通知は極めて粗末で、あなたに変化したことを教えただけですが、どこが変化したかは教えてくれません.

  • reducer関数
    reduxは生成状態の関数をreducerと呼び,2つのパラメータを受け入れ,1つ目の現在の状態,2つ目がイベント内容である.注意:どうしても次の例のように、defaultの処理が欠けていると、default処理が少なく、初期化時にundefined状態になるためエラーが発生します.
    function reducer(state, action) {
        switch (action.type) {
            case 'add':
                return {value: state.value + action.payload}
            case 'dec':
                return {value: state.value + action.payload}
            // default:         
            //     return state
        }
    }
    

    reduxワークフロー
    初期化
    createStoreはreducerを呼び出し、初期状態、すなわちcreateStoreの2番目のパラメータを入力します.呼び出し後、初期状態が得られ、保存されます.
    実行時
    トリプルステップ:
     dispatch       => store  reducer=>     subscribe
    

    プラグイン
    プラグインはstore.dispatchをブロックする方法で、書き方は固定されています.次はログプラグインを例に挙げます.
    function logger({dispatch, getState}) {
        // dispatch         dispatch
        return (next) => {
            // next        
            return (action) => {
                //         
                console.log('before log', action, getState())
                next(action)
                console.log('after log', getState)
            }
        }
    }
    
    const store = createStore(reducer,applyMiddleware(logger))
    

    プラグインは、シリアルコールチェーンを形成することができる.上記の例のapplyMiddlewareメソッドはreduxによって提供され、パラメータは複数のプラグインが可能であり、複数のプラグインを直列に接続する役割を果たす.
    reduxその他
    reduxの公式サイトのその他の内容はすべてプログラミングの規範と技巧を話しています
    魔法文字列とオブジェクトの取り消し
    上記の例では,イベントを書く際には,直接文字列,例えば「add」,「dec」を用い,複数の場所で用いるとエラーが発生しやすい.プログラミングでは、このようなエラーが発生しやすい文字列を「魔法」文字列と呼びます.解決策は定数を定義することです.
    const TYPE_ADD="TYPE_ADD"
    const TYPE_DEC="TYPE_DEC"
    

    同じように、イベントを生成する方法もあります.
    function createAddAction(value){
    	return {type:TYPE_ADD,payload:value}
    }
    

    combineReducers複数のreducerをマージ
    複数のステータスコンテンツ、例えばuserのステータス、postのステータスがあれば、1つのファイルに書くと膨大になります.だから、combineReducersという方法で合併します
    function userReducer(state, action) {
       //  
    }
    function postReducer(state, action) {
       //  
    }
    const reducer = combineReducers({user: userReducer, post: postReducer})
    

    こうして生まれたstateは
    {
       user:{}
       post:{}
    }
    

    ひどうきよびだし
    正確には、reduxは非同期をサポートしていません.reducerは同期しなければならないからです.storeはdispatchからのactionを受信した後,reducerを直接呼び出し,結果としてこのメカニズムは変更できない.すべての非同期は、dispatchの前に発生しなければなりません.だから、非同期は自分で管理しなければなりません.いくつかのプラグインがあり、非同期に協力することができます.原理はdispatchメソッドをブロックし、actionタイプやコンテンツに基づいて、対応する操作を実行します.
  • redux-thunkはactionを関数
  • とすることができる.
  • redux-sagaはaction.typeを傍受し、特定のactionを引き継ぎ、いくつかの非同期動作
  • をトリガする.
  • redux-promise actionをPromiseオブジェクト
  • とすることができる.
    リスニング結果
    redux.subscribeはステータスが変化しただけで、どのコンテンツが変化したのか分からないので、redux-observerで指定したコンテンツをリスニングできます.
    react-redux接着剤
    reduxがreactと結合する場合、react-reduxを使用しなくても動作します.ステータスが変更されたらstore.subscriberでreact再レンダリングを通知
    import React from 'react';
    import ReactDOM from 'react-dom';
    import {createStore} from "redux";
    
    function reducer(state, action) {
       switch (action.type) {
           case 'add':
               return {value: state.value + action.payload}
           case 'dec':
               return {value: state.value - action.payload}
           default:
               return state
       }
    }
    
    const store = createStore(reducer, {value: 1})
    const subscriber = () => {
         ReactDOM.render(
            <div>
                <div>{store.getState().value}</div>
                <button onClick={() => store.dispatch({type: 'add', payload: 1})}> 1</button>
                <button onClick={() => store.dispatch({type: 'dec', payload: 1})}> 1</button>
            </div>,
            document.getElementById('root')!
        )
    };
    store.subscribe(subscriber)
    

    このように書くと、主な欠陥はコンポーネントがstoreと密接に結合しており、デバッグと多重化に不利であるため、react-reduxを用いて結合と接着を解くことである.
    Providerとconnect
    主に2つの内容:Providerコンポーネントとconnectメソッドです.Providerはグローバルなステータスプロバイダを提供するために使用され、connectは通常のComponentを包み、Providerが提供したステータスを受信することができます.
    import React from 'react';
    import ReactDOM from 'react-dom';
    import {createStore} from "redux";
    import {Provider,connect} from 'react-redux'
    
    function reducer(state, action) {
        switch (action.type) {
            case 'add':
                return {value: state.value + action.payload}
            case 'dec':
                return {value: state.value - action.payload}
            default:
                return state
        }
    }
    
    const store = createStore(reducer, {value: 1})
    
    //       
    
    class Counter extends Component{
       render(){
         return(
         <div>
           <div>{this.props.value}</div>
           <button onClick={this.props.addMethod}> 1</button>
           <button onClick={this.props.decMethod}> 1</button>
         </div>
        ) 
       }
    }
    function mapStateToProps(state){
    	return {
    	  value:state.value
    	}
    }
    function mapDispatchToProps(dispatch){
        return {
          addMethod:()=>dispatch({type: 'add', payload: 1})
          decMethod:()=>dispatch({type: 'dec', payload: 1})
        }
    }
    const WrapedCounter=connect(mapStateToProps,mapDispatchToProps)(Counter)
    
    ReactDOM.render(
        (
           <Provider store={store}>
               <WrapedCounter/>
           </Provider>
         ),
         document.getElementById('root')
    )       
    

    connectメソッドには2つの関数パラメータが必要です.1つはmapStateToPropsで、storeのステータスをコンポーネントのプロパティにマッピングします.一つはmapDispatchToPropsで,イベントを送信する方法をコンポーネントの属性にマッピングする.
    まとめ
    読んでくれてありがとう