redux react 使用

圖片說明數據流向

輸入圖片說明 輸入圖片說明

- 數據流向:

  • 首先,用戶發出 Action。
  • store.dispatch(action);
  • 而後,Store 自動調用 Reducer,而且傳入兩個參數:當前 State 和收到的 Action。 Reducer 會返回新的 State 。
  • let nextState = todoApp(previousState, action);
  • State 一旦有變化,Store 就會調用監聽函數。
  • // 設置監聽函數
  • store.subscribe(listener);
  • listener能夠經過store.getState()獲得當前狀態。若是使用的是 React,這時能夠觸發從新渲染 View。
  • function listerner() {
  • let newState = store.getState();
  • component.setState(newState);
  • }

在每一個頁面中使用配置:

  • 1引入react和react-redux的connect方法
  • 用class定義組件,在頁面底部導出,導出時connect一下
  • 並用serverData統一接收:store.xxxState

在每一個頁面中使用:

  • 直接this.props.dispatch(actionCreator( 對應要傳遞的參數));
  • 這個方法是由對應的業務邏輯的方法執行的,
  • 頁面首次加載也可放在鉤子函數裏面
import React from 'react';
import { Icon, Tabs, Card, Flex, WingBlank, WhiteSpace } from 'antd-mobile';
import { StickyContainer, Sticky } from 'react-sticky';
import Mycard from '../../../components/marketCard'
import NavBar from '../../../components/topNavBar'
import { connect } from 'react-redux';
import * as fetchData from '../../../redux/actions/actions_fetchServerData'
import RecordTop from '../components/TransactionRecord/RecordTop'
import RecordItem from '../components/TransactionRecord/recordItem'
import { Helmet } from 'react-helmet'
class txRecordPage extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
        };
        this.props.dispatch(fetchData.fetchMyTransactionRecord(null, (ret) => { }))
    }
    componentWillMount() {
        this.props.dispatch(fetchData.fetchMyTransactionRecord(null, (ret) => { }))
    }
    componentDidMount() {
    }
    render() {
        const { isLoading, serverError, recordItemData, recordTopData } = this.props.serverData
        console.log(recordTopData)
        return (
            <div>
                <Helmet>
                    <title>交易記錄</title>
                </Helmet>
                <RecordTop data={recordTopData} />
                <RecordItem data={recordItemData} />            
            </div>
        );
    }
}

const mapStateToProps = store => {
    return {
        serverData: store.Transaction_recordState,
    }
}
export default connect(mapStateToProps)(txRecordPage);

創建action creator

    • import * as TYPES from './types'; 引入對應的動做狀態
    • import request from '../../utils/request' 引入獲取數據的方法
    • import config from '../../utils/config' 引入對應的url config
  • 在這個裏面 ,能夠寫各類動做類型的action creator, 好比:收藏功能,置頂功能,點擊刪除功能
//收藏功能
export function mineFavorateCollect(id,isCollect){
    return (dispatch)=>{
        dispatch({
            'type':TYPES.MINE_FAVORATE_UNCOLLECT,
            'isCollect':isCollect,
            'idValue':id,
        })
    }
}
//置頂功能
export function mineFavorateToTop(idTop,isToTop){
    return (dispatch)=>{
        dispatch({
            'type':TYPES.MINE_FAVORATE_TOTOP,
            'isToTop':isToTop,
            'idTop':idTop,
        })
    }
}

獲取數據方法的文件

  1. 定義一個從服務器獲取數據方法的文件 fetch_data
  2. 先引入或者定義從服務器fecth數據的方法
  3. 參數包括:token, url ,fetchType ,callback, fakeData_ needToDelete
  4. 以下:
function fetchDataFromServer(token, url, fetchType, callback, fakeData_needToDelete) {
    return (dispatch) => {
        dispatch({
            'type': fetchType.fetching,
        })
        var params = { 'token': token }
        fetch(url, {
            method: 'POST',
            mode: "no-cors",
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(params)
        }).then((ret) => {
            dispatch({
                'type': fetchType.received,
                // 'data': ret,
                'data': fakeData_needToDelete
            })
            callback(ret)
        }).catch((error) => {
            dispatch({
                'type': fetchType.error,
                'data': error
            })
            callback(error)
        });
    }
}
request.getWithToken = (url, token, callback) => {
    // console.log('url:' + url);
    return fetch(url, {
        method: 'GET',
        headers: { //header
            'Content-Type': 'application/json',
            'Authorization': token
        },
    }).then((response) => response.json())
        .then((responseData) => { // 上面的轉好的json
            // console.log(responseData);
            if (responseData.code === '0') {
                callback({ 'isSuccess': true, "data": responseData.data });//返回成功的交易id
            } else {
                callback({ 'isSuccess': false, "data": responseData.msg });//返回錯誤,通常是充太多了,通常累計不超過1個eth

            }
        }).catch((error) => {
            // console.log(error);
            // callback({ 'isSuccess': false, "data": "network error!" });//網絡鏈接失敗
        });

在action 中:(fetchTypes.js)

  • 導出對應的動做和狀態的動做
export const FETCH_MY_TRANSACTION_RECORD = {
    received: "FETCH_TRANSACTION_RECORD_RECEIVED",
    fetching: "FETCH_TRANSACTION_RECORD_FETCHING",
    error: "FETCH_TRANSACTION_RECORD_ERROR"
}

在reducer中,

  • 1引入對應的動做類型
  • 2 初始化要獲得的變量值的類型
  • 3 引入 對應的action type.received or error or fething
  • 用swith case 匹配不一樣的狀態,賦值
  • 4 若是一個接口請求多個組件的數據,要在這裏分別初始化,和根據狀態分別賦值;
import * as fetchTypes from '../actions/fetchTypes'
const initialState = {
    isLoading: false,
    recordItemData:[],
    recordTopData:[],
    serverError:false,
}
export default function Transaction_record_Reducer(state = initialState, action) {

    switch (action.type) {
                
        case fetchTypes.FETCH_MY_TRANSACTION_RECORD.received:
        console.log( action.data)
            return {              
                ...state,
                recordTopData: action.data.recordTopData,
                recordItemData: action.data.recordItemData,
                serverError: false,
                isLoading: false,
            };
            break;
        case fetchTypes.FETCH_MY_TRANSACTION_RECORD.fetching:
            return {
                ...state,
                serverError: false,
                isLoading: true,
            };
            break;
        case fetchTypes.FETCH_MY_TRANSACTION_RECORD.error:
            return {
                ...state,            
                serverError: false,
                isLoading: false,
            };
            break; 
        default:
            return state;
    }

}

在root reducer中集成進去

import { combineReducers } from 'redux'
import myMarketPage from './reducer_myMarketPage'
import findPage from './reducer_findPage'
const rootReducer = combineReducers({
    marketPageState: myMarketPage,
    findPageState: findPage,
})
export default rootReducer

在store中,將root reducer 中的數據傳入store中

import { createStore, applyMiddleware } from 'redux';
import rootReducer from '../reducers/root';
import thunk from 'redux-thunk';

let createStoreWithMiddleware = applyMiddleware(thunk)(createStore);
let store = createStoreWithMiddleware(rootReducer);
export default store;

在頁面的根組件下,引入react-redux ,並用provider包裹,並將其導出react

import React, { Component } from 'react';
import Router from './components/framework/router'
import store from './redux/store/store'
import { Provider } from 'react-redux';

class App extends Component {
  render() {
    return (
      <div className="App">
        <Router />
      </div>
    );
  }
}
const AppWithRedux = () => (
  <Provider store={store}>
    <App />
  </Provider>
)
export default AppWithRedux;
相關文章
相關標籤/搜索