Redux React-Redux瞭解

一.Redux 解析

1).統一數據管理
	將所需的數據提取到state中統一進行管理。當渲染後我們希望更改狀態,封裝更改狀態的方法(dispatch)
2).實現dispatch
	不要直接更改狀態而是使用dispatch方法進行狀態的更改,派發一個帶有type的屬性來進行狀態的更改,但是依然無法阻止用戶更改狀態.
3).createStore的實現
	將狀態放到了createStore函數中,目的是隔離作用域,並且再內部返回深度克隆的對象,這樣用戶無法再通過外界更改狀態。但是狀態應該由我們自身來控制,應該是外界傳入的,所以要將狀態拿出createStore。並且判斷的邏輯也應該由我們自己來編寫
4).reducer的實現
	我們已將需要自己處理的邏輯提取出來,但是我們每次dispatch時都需要自己觸發視圖的更新,我們希望採用發佈訂閱來實現。
5).訂閱函數
	我們redux中常用的方法已經封裝完成我們將封裝好的邏輯抽離成redux.js

二.Redux深入

2.1 redux文件拆分
	store
	    │  action-types.js
	    │  index.js
	    │
	    ├─actions
	    │      counter.js
	    │
	    └─reducer
	            counter.js
	            
	   action-types用來存放需要的常量
	   counter中存放reducer的邏輯
	   store中的index文件用來創建store	
	   action文件夾中的counter,用來生成對應組件的action對象
2.2 實現多個counter
在redux中只能擁有一個store所以我們需要將多個狀態進行合併,狀態是通過reducer返回的,所以我們可以將多個reducer進行合併達到合併狀態的目的。
		│  index.js
		│  redux.js
		│
		├─components
		│      counter1.js
		│      counter2.js
		│
		└─store
		    │  action-types.js
		    │  index.js
		    │
		    ├─actions
		    │      counter1.js
		    │      counter2.js
		    │
		    └─reducer
		            counter1.js
		            counter2.js
		            index.js
	action-types新增counter2處理的常量
	對應的counter2中的action也進行更改

三. React-Redux

1.爲什麼需要高階組件
	從本地存儲中獲取數據放到輸入框內的邏輯應該就是公用邏輯。這時我們就要使用高階組件,也就是將組件在原有的基礎上進行包裝。
2.實現高階組件
	我們將公共的邏輯拿到外層組件,處理好後以屬性的方式傳遞給原本的組件,爲此高階組件就是一個 React 組件包裹着另外一個 React 組件
3.context的用法
	react是單向數據流,我們想傳遞數據需要一層層向下傳遞,數據傳遞變得非常麻煩,我們可以用context實現數據的交互
		1) 父 childContextTypes getChildContext函數
		2) 子 contextTypes
import React from 'react';
import ReactDOM from 'react-dom';
import Counter from "./components/Counter";
import store from './store/index';
import {Provider} from 'react-redux';
ReactDOM.render(
  <Provider store={store}>
    <Counter/>
  </Provider>,window.root);
// counter組件
class Counter extends React.Component {
  render(){
    return <div>
      數量:{this.props.number}
      <button onClick={()=>{this.props.add(1)}}>+</button>
      <button  onClick={()=>{this.props.minus(1)}}>-</button>
      </div>
  }
}
export default connect(state=>({...state}),dispatch=>({
  add:(amount)=>{dispatch(actions.add(amount))},
  minus:(amount)=>{dispatch(actions.minus(amount))}
}))(Counter)

四.MiddleWare的使用

1.logger中間件
	在控制檯查看更改前後的狀態
2.實現redux-thunk中間件
	實現派發異步動作,actionCreator可以返回函數,可以把dispatch的權限交給此函數
3.實現redux-promise中間件
	返回一個實例 ,支持異步請求  看resolve  reject情況

五. Redux 源碼仿寫

 	 <div id="title"></div>
    <div id="content"></div>
  // state  getState  dispatch   subscribe
        // subscribe : 訂閱;可以訂閱一些方法,當執行完dispatch之後,會把訂閱的方法執行
        const CHANGE_TITLE_TEXT = "CHANGE_TITLE_TEXT";
        const CHANGE_CONTENT_COLOR = "CHANGE_CONTENT_COLOR";
        function createStore(reducer) {
            let state;
            let listeners = [];
            let getState = () => JSON.parse(JSON.stringify(state));
            function dispatch(action) {
                state = reducer(state, action);
                // 調用dispatch就會發布listener中的方法;
                listeners.forEach(item => {
                    if (typeof item === "function") {
                        item();
                    }
                })
            }
            dispatch({});
            function subscribe(fn) {
                listeners.push(fn);
                // 返回一個取消訂閱的方法,當返回值執行時,取消對應的訂閱
                return () => {
                    listeners = listeners.filter(item => item !== fn);
                }
            }
            return {
                getState,
                dispatch,
                subscribe
            }
        }
        let initState = {
            title: { color: "red", text: "xxWOxx" },
            content: { color: "yellow", text: "qqNIqq" }
        };

        function reducer(state = initState, action) {// 形參
            switch (action.type) {
                case CHANGE_TITLE_TEXT:
                    return { ...state, title: { ...state.title, text: action.text } };
                case CHANGE_CONTENT_COLOR:
                    return { ...state, content: { ...state.content, color: action.color } }
            }
            return state;
        }
        let store = createStore(reducer);

        function renderTitle() {
            let title = document.getElementById("title");
            title.innerHTML = store.getState().title.text;
            title.style.color = store.getState().title.color;
        }
        function renderContent() {
            let content = document.getElementById("content");
            content.innerHTML = store.getState().content.text;
            content.style.color = store.getState().content.color;
        }
        function renderApp() {
            renderTitle();
            renderContent();
        }
        renderApp();
        setTimeout(function () {
            store.dispatch({ type: CHANGE_TITLE_TEXT, text: "好好學習" });
            store.dispatch({ type: CHANGE_CONTENT_COLOR, color: "blue" })
            // renderApp();
        }, 2000)
        // 訂閱renderApp這個方法,然後執行dispatch,就會發布這個方法;
        // let f = store.subscribe(renderApp);
        // f();// 取消訂閱
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章