react+react-router+react-redux全家桶小項目開發(fā)過程分享

react-ele-webapp

項目地址 :https://github.com/kliuj/react-ele-webapp

run

下載完項目

npm install

然后

npm run dev 即可

基于 react react-router redux 的項目,主要是為了學(xué)習(xí)實戰(zhàn)react陪白。數(shù)據(jù)都是固定的买窟,從餓了么接口臨時抓的,模擬了一個0-100ms的異步數(shù)據(jù)延遲谓厘,感謝餓了么磁浇。

以下內(nèi)容是項目開發(fā)的過程和一些思考求冷,按照這個過程至少能保證實現(xiàn)一個相對完整的react全家桶項目

內(nèi)容參考

react文檔:http://reactjs.cn/react/docs/getting-started-zh-CN.html

react-router 文檔地址 :https://reacttraining.com/react-router/web/guides/quick-start

react-router 中文版參考:http://www.uprogrammer.cn/react-router-cn/index.html

redux文檔參考:http://redux.js.org/

redux中文文檔:http://cn.redux.js.org/

搭建項目:

建立項目目錄,安裝package.json翰撑,配置webpack.config
做好基礎(chǔ)依賴工作罩旋,摘自package.json的一部分內(nèi)容

    "devDependencies": {
        "babel-core": "^6.23.1",
        "babel-loader": "^6.4.0",
        "babel-preset-es2015": "^6.22.0",
        "babel-preset-react": "^6.23.0",
        "html-webpack-plugin": "^2.28.0",
        "jshint": "^2.9.4",
        "jshint-loader": "^0.8.4",
        "react": "^15.2.0",
        "react-dom": "^15.2.0",
        "react-router": "^2.0.0",
        "redux": "^3.6.0",
        "webpack": "^2.2.1",
        "webpack-dev-server": "^2.4.1"
    } //JAVASCRIPT

項目模塊結(jié)構(gòu)組織一些基礎(chǔ)工作

開始進行開發(fā)一個項目除了技術(shù)選型之外,還有許多基礎(chǔ)東西要先設(shè)計好眶诈,一個好的組織設(shè)計要可以為以后的提高工作效率涨醋。我這方面還有很多欠缺,目前主要考慮了3個模塊的設(shè)計:

1:后臺接口通信層:model.js 主要處理統(tǒng)一接口的請求發(fā)送和回調(diào)册养,放在一起更有利于后期維護东帅,也增加可閱讀性

    //接口對應(yīng)的url,這里只做演示
    const uris = {
          index_entry : fetchData.index_entry,
          hot_search_words : fetchData.hot_search_words
    }
    //接口調(diào)用層
    export default function send(url,postData,successCallback,errCallback){
        //模擬延遲球拦,假接口
        let promise = new Promise(function(resolve,reject){
            setTimeout(function(){
                resolve(fetchData[url])
            },Math.random()*100)
        })
        promise.then(function(data){
            successCallback(data)
        })
    }

2:本地數(shù)據(jù)緩存維護:baseStore.js 主要處理頁面之間的跳轉(zhuǎn)返回靠闭,增加更多的自主性和擴展性

    // 自動存儲瀏覽記錄
    export function  saveFrom(prop) {
          let name = prop.pagename,
              transit =  prop.location,
              qhfrom = transit.query.qhfrom ,//默認全部返回首頁
              para = transit.query.para ? JSON.parse(transit.query.para) : '';
          if(!qhfrom) return false;
          let paths  = localStorage.getItem("FromUrlStore") ? JSON.parse(localStorage.getItem("FromUrlStore")) : {};
          if (localStorage) {
            paths[name] = {
              'name':qhfrom,//存儲來源頁面
              'para':para //存儲來源頁面的參數(shù)
            }
            localStorage.setItem("FromUrlStore", JSON.stringify(paths));
          }
      }
   //存儲頁面的來源,統(tǒng)一管理   

3:公共方法的處理:baseFun.js 主要用來定義一些公用的模塊方法

    //放置公用函數(shù) 
    export function showToast(){
        ...
    }

使用react-router初始化頁面

    import React from 'react'
     import { render } from 'react-dom'
     import { Router, Route, Link,hashHistory ,IndexRedirect,IndexRoute} from 'react-router'
     import Home from './components/home.jsx'
     import Discover from './components/discover.jsx'
     const App = React.createClass({
       render() {
         return (
           <div>
             <footer>
                 <Link to="/home">外賣</Link> 
                 <Link to="/discover?qhfrom=home">發(fā)現(xiàn)</Link>
             </footer>
             {this.props.children}
           </div>
         )
       }
     })
     const route = (
          <Router history={hashHistory}>
             <Route path="/" component={App}>
               <IndexRoute component={Home} />
               <Route path="home" component={Home} />
               <Route path="discover" component={Discover} />
             </Route>
           </Router>
     )
     render(route, document.getElementById("app"))

代碼簡單介紹:
因為沒有后臺坎炼,采用的 hashHistoryhash路由)愧膀,關(guān)于hash路由可以參考:https://github.com/kliuj/spa-routers 有簡單的介紹。

這個是router的跳轉(zhuǎn) <Link to="/home">外賣</Link>
這個是加載子路由組件 {this.props.children}
這個是默認的跳轉(zhuǎn)頁面 <IndexRoute component={Home} />

處理首頁的滾動列表

首頁主要分成了4個組件
底部導(dǎo)航 + 滾動列表 + 單個產(chǎn)品 + 首頁搜索框

滾動列表封裝了一個簡單的組件

    <List
        list={Pro}  //每個產(chǎn)品item組件
        pagename={'home'} //跳轉(zhuǎn)產(chǎn)品列表的上級頁面  用來處理返回
        data={this.state.productList} //需要渲染的數(shù)據(jù)
        onScroll = {this.getMore.bind(this)}//滾動加載函數(shù)
    />
    在scrollList組件里面監(jiān)聽了滾動事件進行自動加載的處理

react-redux 處理登錄和登出

使用redux的原因:用戶信息和登錄是兩個不同的組件谣光,也沒有父子級的關(guān)系檩淋,但是需要進行數(shù)據(jù)狀態(tài)共享和相互影響。詳細信息可以看上面的官方文檔,我這里就簡單說一下我這個項目的應(yīng)用蟀悦。

定義常量 actionTypes.js

    //登入成功
    export const LOG_SUCCESS = 'LOG_SUCCESS'
    //正在登錄
    export const LOG_ING = 'LOG_ING'
    //注銷登錄
    export const LOG_OUT = 'LOG_OUT'
    //主要是統(tǒng)一保存狀態(tài)對應(yīng)的名稱

定義具體的觸發(fā)操作 actions/login.js

    //注銷 同步
    export function log_out (){
        return {
            type:actionTypes.LOG_OUT
        }
    }
    //登入 異步
    export function log_in (obj){
        return dispatch=>{
            //pending  正在進行登錄的狀態(tài)
            dispatch({type:actionTypes.LOG_ING})
            //開始發(fā)送異步請求登錄
            new Promise((resolve,reject)=>{
                ...
            }).then(res=>{
                dispatch(res)
            })
        }
    }
    //異步狀態(tài)需要使用中間件

處理數(shù)據(jù) reducers/login.js

    export default function(state = initialData,action){
        switch(action.type){
            case actionTypes.LOG_SUCCESS:
                return {
                    loginstate:1,
                    username:action.username
                }
                break
            case actionTypes.LOG_ING:
                return{
                    loginstate:-1,
                    username:'正在登錄'
                }   
            case actionTypes.LOG_OUT:
                return initialData
                break
            default :
                return initialData  
        }
    }

使用中間件創(chuàng)建store層 store/store.js

    import {createStore, applyMiddleware} from 'redux'
    import thunk from 'redux-thunk'
    //合并的多個reducer媚朦,解耦
    import rootReducer from '../reducers/index.js'
    const middlewares = [thunk]
    const createStoreWithMiddleware = applyMiddleware(...middlewares)(createStore)
    export default function configureStore(initialState){
        return createStoreWithMiddleware(rootReducer,initialState)
    }

在路由層引入

    import {Provider} from 'react-redux'
    const store = configureStore()
    const route = (
      <Provider store={store}>
          <Router history={hashHistory}>
              ...
          </Router>
      </Provider>
    )

組件里面使用

    import { connect } from 'react-redux'
    import {log_out} from '../../actions/login.js' //操作
    ...
    ...
    function mapStateToProps(userinfo){
        let {login} = userinfo //這個是返回的所有reducer,我們只用當(dāng)前需要的日戈,參考 reducers/index.js 內(nèi)容
        return login
    }
    export default connect(mapStateToProps)(UserInfo)
    //這個時候就可以在當(dāng)前組件狀態(tài)的  this.props 獲取到這個 login 數(shù)據(jù)询张,
    //操作的時候  
    const {dispatch} = this.props;
    dispatch(log_out())
    //這時候就可以操作redux狀態(tài)的數(shù)據(jù),每次數(shù)據(jù)改變都會下發(fā)給所有接收的組件

以上浙炼,我們就使用了許多東西完成了一個簡單的小項目

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末份氧,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子弯屈,更是在濱河造成了極大的恐慌蜗帜,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件资厉,死亡現(xiàn)場離奇詭異厅缺,居然都是意外死亡,警方通過查閱死者的電腦和手機酌住,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門店归,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人酪我,你說我怎么就攤上這事∏胰” “怎么了都哭?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長逞带。 經(jīng)常有香客問我欺矫,道長,這世上最難降的妖魔是什么展氓? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上剖笙,老公的妹妹穿的比我還像新娘呻逆。我一直安慰自己,他們只是感情好空入,可當(dāng)我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布络它。 她就那樣靜靜地躺著,像睡著了一般歪赢。 火紅的嫁衣襯著肌膚如雪化戳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天埋凯,我揣著相機與錄音点楼,去河邊找鬼扫尖。 笑死,一個胖子當(dāng)著我的面吹牛掠廓,可吹牛的內(nèi)容都是我干的换怖。 我是一名探鬼主播,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼却盘,長吁一口氣:“原來是場噩夢啊……” “哼狰域!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起黄橘,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤兆览,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后塞关,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體抬探,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年帆赢,在試婚紗的時候發(fā)現(xiàn)自己被綠了小压。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡椰于,死狀恐怖怠益,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情瘾婿,我是刑警寧澤蜻牢,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站偏陪,受9級特大地震影響抢呆,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜笛谦,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一抱虐、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧饥脑,春花似錦恳邀、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至框往,卻和暖如春鳄抒,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工许溅, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留瓤鼻,地道東北人。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓贤重,卻偏偏與公主長得像茬祷,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子并蝗,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容