图片说明数据流向
- 数据流向:
- 首先,用户发出 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,
})
}
}
获取数据方法的文件
- 定义一个从服务器获取数据方法的文件 fetch_data
- 先引入或者定义从服务器fecth数据的方法
- 参数包括:token, url ,fetchType ,callback, fakeData_ needToDelete
- 如下:
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;