搜尋
首頁web前端js教程電影蒐集的小應用react技術棧實踐

電影蒐集的小應用react技術棧實踐

Dec 18, 2017 pm 03:43 PM
react應用科技

本文主要和大家分享電影蒐集的小應用react技術堆疊實踐,希望能幫助大家。

主要功能

  • 爬取豆瓣電影資訊並錄入MongoDB

  • 電影列表展示,分類、搜尋

  • 電影詳情展示及附件管理

  • 註冊、登入

  • 權限控制,一般使用者可以輸入、收藏,administrator輸入、修改、刪除

  • 用戶中心,我的收藏清單

電影蒐集的小應用react技術棧實踐

##一些總結

前端

前端使用了react,redux加redux-saga,對redux簡單總結一下,同時記錄一個前後介面呼叫有依賴關係的問題

  • redux

一句話總結redux,我覺的就是將組件之間的縱向的props傳遞和父子組件間的state愛恨糾纏給打平了,將一種縱向關係轉變成

多個元件和一個獨立出來的狀態物件直接互動,這樣之後,程式碼結構確實看上去更加清晰了。

redux的核心概念,action,reducer,和store

action就是說明我要操作一個狀態了,怎麼操作是reducer的事,而所有狀態都儲存在store中,store發出動作並交由指定的reducer來處理

redux強制規範了我們對狀態的操作,只能在action和reducer這些東西中,這樣,原本錯綜複雜的業務邏輯處理就換了個地,限制在了action和reducer中,組件看起來就很乾淨了。其實,該複雜的東西在哪裡放都複雜,只不過現在更清晰一點

使用redux不好的地方就是太繁瑣了,定義各種action,connect各種組件。 。 。 。 。現在又出來一個Mobx,不明覺厲,反正大家都說好~

  • redux-saga

redux-saga用來處理非同步呼叫啥的,借助於generator,讓非同步程式碼看起來更簡潔,常用的有

take,takeLatest,takeEvery,put,call,fork,select,使用過程中遇到一個介面呼叫有前後依賴關係的問題,比較有意思

描述一下:

  1. 有一個介面

    /api/user/checkLogin,用來判斷是否登錄,在最外層的組件的componentDidMount中觸發action來發起這個請求,並且接口返回狀態是登錄的話,還發送一個獲取用戶信息的

  2. #
    function* checkLogin() {
        const res = yield Util.fetch('/api/user/checkLogin')
        yield put(recieveCheckLogin(!res.code))
        if (!res.code) {
            //已登录
            yield put(fetchUinfo())
        }
    }
    export function* watchCheckLogin() {
        yield takeLatest(CHECK_LOAGIN, checkLogin)
    }
  1. 然後我有一個電影詳情頁元件,在這個元件的

    componentDidMount中會啟動/api/movies/${id} 介面取得電影訊息,如果使用者是登入狀態的話,也會發起一個獲取電影附件資訊的介面/api/movies/${id}/attach整個步驟寫在一個generator中

  2. function* getItemMovie(id) {
        return yield Util.fetch(`/api/movies/${id}`)
    }
    
    function* getMovieAttach(id) {
        return yield Util.fetch(`/api/movies/${id}/attach`)
    }
    
    function* getMovieInfo(action) {
        const { movieId } = action
        let { login } = yield select(state => state.loginStatus)
        const res = yield call(getItemMovie, movieId)
        yield put(recieveItemMovieInfo(res.data[0]))
        if (res.data[0].attachId && login) {
            const attach = yield call(getMovieAttach, movieId)
            yield put(recieveMovieAttach(attach.data[0]))
        }
    }
    
    export function* watchLoadItemMovie() {
        yield takeLatest(LOAD_ITEM_MOVIE, getMovieInfo)
    }
  1. #用戶登入了,轉到詳情,流程正常,但如果在詳情頁刷新了頁面,取得附件的介面沒觸發,原因是此時checkLogin介面還沒回傳結果,

    state.loginStatus狀態還是false,上面就沒走到if中

  2. 一開始想著怎麼控制一些generator中yield的先後順序來解決(如果用戶沒有登入的話,再發一個CHECK_LOAGIN,結果回傳了流程再繼續),但存在CHECK_LOAGIN呼叫兩次,如果登入了,還會再多一次獲取用戶資訊的介面呼叫的情況,肯定不行

  3. function* getMovieInfo(action) {
        const { movieId } = action
        let { login } = yield select(state => state.loginStatus)
        const res = yield call(getItemMovie, movieId)
        yield put(recieveItemMovieInfo(res.data[0]))
        // if (!login) {
        //     //刷新页面的时候,如果此时checklogin接口还没返回数据或还没发出,应触发一个checklogin
        //     //checklogin返回后才能得到login状态
        //     yield put({
        //         type: CHECK_LOAGIN
        //     })
        //     const ret = yield take(RECIEVE_CHECK_LOAGIN)
        //     login = ret.loginStatus
        // }
        if (res.data[0].attachId && login) {
            const attach = yield call(getMovieAttach, movieId)
            yield put(recieveMovieAttach(attach.data[0]))
        }
    }
  1. #最終的辦法,分解generator的職責,componentWillUpdate中合適的觸發獲取附件的動作

  2. //将获取附件的动作从 getMovieInfo这个generator中分离出来
    function* getMovieInfo(action) {
        const { movieId } = action
        const res = yield call(getItemMovie, movieId)
        yield put(recieveItemMovieInfo(res.data[0]))
    }
    function* watchLoadItemMovie() {
        yield takeLatest(LOAD_ITEM_MOVIE, getMovieInfo)
    }
    function* watchLoadAttach() {
        while (true) {
            const { movieId } = yield take(LOAD_MOVIE_ATTACH)
            const { attachId } = yield select(state => state.detail.movieInfo)
            const attach = yield call(getMovieAttach, movieId)
            yield put(recieveMovieAttach(attach.data[0]))
        }
    }
    
    //组件中
    componentWillUpdate(nextProps) {
            if (nextProps.loginStatus && (nextProps.movieInfo!==this.props.movieInfo)) {
                //是登录状态,并且movieInfo已经返回时
                const { id } = this.props.match.params
                this.props.loadMovieAttach(id)
            }
    }
  1. 總結,合理使用元件的鉤子函數,generator中不要處理太多操作,增加靈活性

後端

後端採用express和mongodb,也用到了redis,主要技術點有

使用pm2來管理node應用程式及部署程式碼,mongodb中開啟身分認證,使用token+ redis來做身分認證、在node中寫了寫單元測試,還是值得記錄的

  • #使用jwt + redis 來做基於token的使用者身分認證

#基於token的認證流程

  1. 客戶端發起登入請求

  2. #服務端驗證使用者名稱密碼

  3. 驗證成功服務端產生一個token,回應給客戶端

  4. #客戶端之後的每次請求header中都帶上這個token

  5. 服務端對需要認證的介面要驗證token,驗證成功接收請求

#這裡採用jsonwebtoken來產生token,

jwt.sign(payload, secretOrPrivateKey, [options, callback])
使用express-jwt驗證token(驗證成功會把token資訊放在request.user中)

express_jwt({
        secret: SECRET,
        getToken: (req)=> {
        if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') {
            return req.headers.authorization.split(' ')[1];
        } else if (req.query && req.query.token) {
            return req.query.token;
        }
        return null;
    }
    }
為什麼要使用redis

**採用jsonwebtoken產生token時可以指定token的有效期,並且jsonwebtoken的verify方法也提供了選項來更新token的有效期,
但這裡使用了express_jwt中間件,而express_jwt不提供方法來刷新token **

想法:

  1. 客戶端請求登入成功,產生token

  2. 將此token保存在redis中,設定redis的有效期限(例如1h)

  3. 新的請求過來,先express_jwt驗證token,驗證成功, 再驗證token是否在redis中存在,存在說明有效

  4. 有效期內客戶端新的請求過來,提取token,更新此token在redis中的有效期

  5. 客戶端退出登入請求,刪除redis中此token

具體程式碼

  • 使用mocha + supertest + should 來寫單元測試

測試覆蓋了所有接口,在開發中,因為沒什麼進度要求就慢慢寫了,寫完一個接口就去寫一個測試,測試寫也還算詳細,等測試通過了再前端調接口,整個過程還是挺有意思的

mocha 是一個node單元測試框架,類似前端的jasmine,語法也相近

supertest 用來測試node介面的函式庫

#should nodejs斷言函式庫,可讀性很高

測試的一個例子,篇幅太長,就不放在這了

#相關推薦:

React 內部機制探針

React中元件的寫法有哪些

react.js給標識ref,取得內容


以上是電影蒐集的小應用react技術棧實踐的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
Python和JavaScript的未來:趨勢和預測Python和JavaScript的未來:趨勢和預測Apr 27, 2025 am 12:21 AM

Python和JavaScript的未來趨勢包括:1.Python將鞏固在科學計算和AI領域的地位,2.JavaScript將推動Web技術發展,3.跨平台開發將成為熱門,4.性能優化將是重點。兩者都將繼續在各自領域擴展應用場景,並在性能上有更多突破。

Python vs. JavaScript:開發環境和工具Python vs. JavaScript:開發環境和工具Apr 26, 2025 am 12:09 AM

Python和JavaScript在開發環境上的選擇都很重要。 1)Python的開發環境包括PyCharm、JupyterNotebook和Anaconda,適合數據科學和快速原型開發。 2)JavaScript的開發環境包括Node.js、VSCode和Webpack,適用於前端和後端開發。根據項目需求選擇合適的工具可以提高開發效率和項目成功率。

JavaScript是用C編寫的嗎?檢查證據JavaScript是用C編寫的嗎?檢查證據Apr 25, 2025 am 12:15 AM

是的,JavaScript的引擎核心是用C語言編寫的。 1)C語言提供了高效性能和底層控制,適合JavaScript引擎的開發。 2)以V8引擎為例,其核心用C 編寫,結合了C的效率和麵向對象特性。 3)JavaScript引擎的工作原理包括解析、編譯和執行,C語言在這些過程中發揮關鍵作用。

JavaScript的角色:使網絡交互和動態JavaScript的角色:使網絡交互和動態Apr 24, 2025 am 12:12 AM

JavaScript是現代網站的核心,因為它增強了網頁的交互性和動態性。 1)它允許在不刷新頁面的情況下改變內容,2)通過DOMAPI操作網頁,3)支持複雜的交互效果如動畫和拖放,4)優化性能和最佳實踐提高用戶體驗。

C和JavaScript:連接解釋C和JavaScript:連接解釋Apr 23, 2025 am 12:07 AM

C 和JavaScript通過WebAssembly實現互操作性。 1)C 代碼編譯成WebAssembly模塊,引入到JavaScript環境中,增強計算能力。 2)在遊戲開發中,C 處理物理引擎和圖形渲染,JavaScript負責遊戲邏輯和用戶界面。

從網站到應用程序:JavaScript的不同應用從網站到應用程序:JavaScript的不同應用Apr 22, 2025 am 12:02 AM

JavaScript在網站、移動應用、桌面應用和服務器端編程中均有廣泛應用。 1)在網站開發中,JavaScript與HTML、CSS一起操作DOM,實現動態效果,並支持如jQuery、React等框架。 2)通過ReactNative和Ionic,JavaScript用於開發跨平台移動應用。 3)Electron框架使JavaScript能構建桌面應用。 4)Node.js讓JavaScript在服務器端運行,支持高並發請求。

Python vs. JavaScript:比較用例和應用程序Python vs. JavaScript:比較用例和應用程序Apr 21, 2025 am 12:01 AM

Python更適合數據科學和自動化,JavaScript更適合前端和全棧開發。 1.Python在數據科學和機器學習中表現出色,使用NumPy、Pandas等庫進行數據處理和建模。 2.Python在自動化和腳本編寫方面簡潔高效。 3.JavaScript在前端開發中不可或缺,用於構建動態網頁和單頁面應用。 4.JavaScript通過Node.js在後端開發中發揮作用,支持全棧開發。

C/C在JavaScript口譯員和編譯器中的作用C/C在JavaScript口譯員和編譯器中的作用Apr 20, 2025 am 12:01 AM

C和C 在JavaScript引擎中扮演了至关重要的角色,主要用于实现解释器和JIT编译器。1)C 用于解析JavaScript源码并生成抽象语法树。2)C 负责生成和执行字节码。3)C 实现JIT编译器,在运行时优化和编译热点代码,显著提高JavaScript的执行效率。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),