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包裹,并将其导出

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;

猜你喜欢

转载自my.oschina.net/u/3150996/blog/1596014