工做流程

main.js

1.引入Route,createStore,combineReducersweb

const {Router, Route, Redirect, IndexRoute, browserHistory} = ReactRouter;
const {Provider, connect} = ReactRedux;
const { createStore, combineReducers, applyMiddleware, compose} = Redux;
const {syncHistoryWithStore, routerMiddleware, routerReducer, push } = ReactRouterRedux;
const thunkMiddleware = require('redux-thunk');

2.引入組件和reducerjson

const DanbaiPacket = require('Containers/DanbaiPacket');
const DanbaiPacket = require('Containers/DanbaiPacket');

3.綁定reducer,storeredux

const reducer = combineReducers({
  routing: routerReducer,
  localizationReducer: LocalizationReducer,
  accountReducer: AccountReducer,
  notificationReducer: NotificationReducer,
  headlineDetailReducer: HeadlineDetailReducer,
  headlineEditorReducer: HeadlineEditorReducer,
  headlineListReducer: HeadlineListReducer,
  userCollectionsReducer: UserCollectionsReducer,
  userArticlesReducer: UserArticlesReducer,
  signInPopupReducer: SignInPopupReducer,
  notifyMessageReducer: NotifyMessageReducer,
  redPacketReducer: RedPacketReducer,
  danbaiPacketReducer: DanbaiPacketReducer
});

const middleware = routerMiddleware(browserHistory);
let initState = {};

let store = createStore(
    reducer,
    {},
    compose(
      applyMiddleware(thunkMiddleware, middleware),
      (window.RAILS_ENV === 'development' && window.devToolsExtension) ? window.devToolsExtension() : f=>f
    )
);

4.Router結構api

var routes = (
  <Provider store={store}>
    <Router history={skHistory}>
      <Route path="/" component={MainWindow}>
        <Route path="headline_drafts/:id/edit" component={HeadlineEditor}/>
        <Route path="headlines/:id" component={HeadlineDetail} />
        <Route path="headlines" component={HeadlineList}/>
        <Route path="users/:id" component={User}>
          <Route path="articles" component={UserArticlesList} />
          <Route path="collections" component={UserCollectionsList} />
        </Route>
        <Route path="operation_activities_red_packet/:id" component={RedPacket}/>
        <Route path="danbai_packet/:id" component={DanbaiPacket} />
      </Route>
    </Router>
  </Provider>
);

頁面組件

1.define這個組件
引入routerAction, connect作reducer鏈接
引入action中的函數getDanbaiPacket,dispatch到action中處理數據
this.props獲取reducer中的數據
組件上componentWillReceiveProps會受到reducer發來的數據,nextProps包含發來的信息.app

define("Containers/DanbaiPacket", function(require, exports) {
  const { routerActions } = ReactRouterRedux;
  const { connect } = ReactRedux;
  const { getDanbaiPacket } = require('Actions/DanbaiPacketAction');

  var DanbaiPacket = React.createClass({
    getInitialState: function() {
      return {

      };
    },
    componentDidMount: function() {
      this.props.dispatch(getDanbaiPacket(this.props.params.id));
    },
    render: function() {
      const { localization, current_account, danbaiPacketDetail } = this.props;
      
      return (
        <div className="SK-danbai-container">
          aaa
        </div>
      );
    }
  });

  function mapStateToProps(state, ownProps) {
    return {
      localiztion: state.localizationReducer.languages[state.localizationReducer.languages.current],
      current_account: state.accountReducer.current_account,
      danbaiPacketDetail: state.danbaiPacketReducer.danbaiPacketDetail
    };
  }

  return connect(mapStateToProps)(connect(null, routerActions)(DanbaiPacket));
});

2.action
定義Action函數
定義type字段字符串
定義dispatch的函數,返回一個高階函數,傳入dispatch和getState,再dispatch到reducer處理數據
return出type字段和函數,供reducer和組件使用.
post類型的請求,或者不須要將數據掛載到reducer函數上的,不須要dispatch到reducer處理,直接用callback處理返回的數據.ide

//= require ../../util/fetch_posts
//= require ./notify_message_action

define("Actions/DanbaiPacketAction", function(require, exports) {
  const fetch = require('util/FetchPosts');
  const { addNotifyMesaage } = require('Actions/NotifyMessageAction');
  const INIT_DANBAI_PACKET = "INIT_DANBAI_PACKET";

  function initDanbaiPacket(data) {
    return {
      type: INIT_DANBAI_PACKET,
      data: data
    };
  }

  function getDanbaiPacket(id, callback) {
    return (dispatch, getState) => {
      fetch.get({
        url: '/api/events/' + id + ',json',
        dataType: 'json',
        data: {
          sonkwo_client: 'web'
        },
        success: function(res) {
          dispatch(initDanbaiPacket(res))
        },
        error: function(xhr) {
          if (xhr.status === 404) {
            dispatch(addNotifyMesaage("wufazhaodaoziyuan"));
          }
        }
      });
    }
  }

  return {
    INIT_DANBAI_PACKET,
    getDanbaiPacket
  }
});

3.reducer
從action引入type字符串
定義reducer函數,便可以在組件中被獲取的數據
每一個reducer函數都會return出一個對象,這就是這個函數的值,要用Object.assign({}, state, action.data)
state的值會變化,直接action.data的話,那就只有這一個值.
能夠用Object.assign({}, state, {rules: action.data}),
這樣掛載再reducer函數上的key爲rules.
只要掛載再reducer函數上的key值有變化,只要有dispatch,就會觸發組件render
即便有兩個reducer處理函數,也是以dispatch爲準,dispatch後會觸發reducer處理函數,觸發組件render.函數

//= require ../actions/danbai_packet_action

define("Reducers/DanbaiPacketReducer", function(require, exports) {
  const { INIT_DANBAI_PACKET } = require('Actions/RedPacketAction');
  const { combineReducers } = Redux;

  function danbaiPacketDetial(state={}, action) {
    switch (action.type) {
      case INIT_DANBAI_PACKET:
        return Object.assign({}, state, action.data);
      default:
        return state;
    }
  }

  return combineReducers({
    danbaiPacketDetial: danbaiPacketDetial
  });
});

4.子組件
define子組件
使用解構賦值,給rules初始值
也能夠使用componentWillReceivePropspost

define('Components/Example', function(require, exports) {
  var Example = React.createClass({
    getInitialState: function() {
      return {

      };
    },
    componentWillReceiveProps: function() {

    },
    componentDidMount: function() {

    },
    render: function() {
      const { rules = [] } = this.props;

      return (
        <div>
          example
          {
            rules.map((item, index) => {
              return (
                <div key={ index }>
                  id: { item.id },
                  type: { item.type }
                </div>
              )
            })
          }
        </div>
      );
    }
  });

  return Example;
});

在父組件中引入,傳入danbaiPacketDetail.rulesfetch

<Example rules={ danbaiPacketDetail.rules } />

問題總結

1.全部請求都把數據掛在了reducer函數上,且都直接返回,形成數據雜糅,key值衝突,不易處理邏輯,
又形成重複render.
解決:ui

1.post請求或者不須要處理返回數據的,直接callback執行回掉,在action中不須要dispatch到reducer處理.
2.reducer處理數據時,return出來的值整個值,使用Object.assign({}, state, action.data),把數據
所有返回.

2.Modal的ErrorPopup只須要有一個,error爲this.state.error,mode爲"simple"則樣式本身寫.
層疊順序爲:SignInPopup > ErrorPopup > 自身的modal
3.this.props.params.id,this.props.location.query只能在Route中的組件獲取.
4.對每一個接口作錯誤處理.
5.對一些可能先返回undefined的值作保護,能夠用解構賦值初始值.

const {a = []} = this.props;

6.post以後通常有回調,再從新dispatch獲取接口,或者直接在post接口中callbackc處理.

相關文章
相關標籤/搜索