摘要:兄弟組件之間無(wú)法直接通信,它們需要利用同一層的上級(jí)作為中轉(zhuǎn)站。在兩個(gè)地方會(huì)用到,一是通過(guò)提交后需要拿到里面的數(shù)據(jù),二是利用監(jiān)聽(tīng)到發(fā)生變化后調(diào)用它來(lái)獲取新的數(shù)據(jù)。
前言
在學(xué)習(xí)react的過(guò)程中,深深的被react的函數(shù)式編程的模式所吸引,一切皆組件,所有的東西都是JavaScript。React框架其實(shí)功能很單一,主要負(fù)責(zé)渲染的功能,但是社區(qū)很活躍,衍生出了很多優(yōu)秀的庫(kù)和工具。個(gè)人覺(jué)得,想要做好一個(gè)項(xiàng)目,往往需要其他庫(kù)和工具的配合,例如redux管理數(shù)據(jù),react-router管理路由等,掌握基本的webpack配置和es6語(yǔ)法,然后想要提高性能,還有配合react的鉤子函數(shù)和immutable.js,什么時(shí)候組件不需要重新渲染,next.js服務(wù)端渲染等等...
一直有一個(gè)想法就是重構(gòu)自己的博客,剛好這段時(shí)間放假,又剛好學(xué)習(xí)了react,于是就有了這個(gè)項(xiàng)目。
項(xiàng)目地址:https://github.com/k-water/re...技術(shù)棧
如果覺(jué)得不錯(cuò)的話,您可以點(diǎn)右上角 "Star" 支持一下 謝謝! ^_^
前端
react
react-redux
react-thunk
react-router
axios
eslint
maked
highlight.js
antd
es6/7/8
后臺(tái)
spring boot
此項(xiàng)目采用前后端分離的實(shí)現(xiàn),后臺(tái)接口基于RESTful規(guī)范設(shè)計(jì),只提供數(shù)據(jù),前端負(fù)責(zé)路由跳轉(zhuǎn),權(quán)限限制,渲染數(shù)據(jù)等。PS:由于我是個(gè)前端er,所以這里主要講的是前端。
實(shí)現(xiàn)的功能[x] admin增刪查改博客
[x] 博客標(biāo)簽
[x] 博客內(nèi)容markdown
[x] 博客內(nèi)容頁(yè)展示目錄
[x] 返回頂部
[x] markdown代碼高亮
[x] 用戶登錄注冊(cè)
[x] 用戶評(píng)論
[x] 響應(yīng)式
TODO[ ] 博客分類
[ ] 點(diǎn)擊標(biāo)簽搜索相關(guān)博客
[ ] 優(yōu)化首頁(yè)側(cè)邊欄
[ ] 完善歸檔
效果預(yù)覽 首頁(yè) 內(nèi)容頁(yè) 用戶登錄 用戶評(píng)論 后臺(tái)管理 個(gè)人總結(jié) markdown渲染在前端渲染markdown的時(shí)候遇到了一點(diǎn)問(wèn)題,相關(guān)的包很多,但是各種包解析的結(jié)果都有差異,react周邊社區(qū)推薦的是 react-markdown,使用方法也很簡(jiǎn)單
import ReactMarkdown from "react-markdown" const input = "# This is a header And this is a paragraph" ReactDOM.render(, document.getElementById("container") )
但是發(fā)現(xiàn)react-markdown對(duì)表格的支持不太友好,最后采用了marked,結(jié)合highlight.js對(duì)代碼部分實(shí)現(xiàn)高亮
import marked from "marked" import hljs from "highlight.js" componentWillMount() { marked.setOptions({ highlight: code => hljs.highlightAuto(code).value }) }
最后解析出來(lái)的是一個(gè)字符串,還需要將它插入dom中,由于安全問(wèn)題,React不提倡將字符串直接插入dom中,但React保留了一個(gè)API,可以這樣做:
React組件化
react的組件由dom視圖和state組成,state是數(shù)據(jù)中心,它的狀態(tài)決定著視圖的狀態(tài)。react只負(fù)責(zé)UI的渲染,與其他框架監(jiān)聽(tīng)數(shù)據(jù)動(dòng)態(tài)改變dom不同,react采用setState來(lái)控制視圖的更新。setState會(huì)自動(dòng)調(diào)用render函數(shù),觸發(fā)視圖的重新渲染,如果僅僅只是state數(shù)據(jù)的變化而沒(méi)有調(diào)用setState,并不會(huì)觸發(fā)更新。說(shuō)到組件,就必須了解react組件的生命周期,官方的圖解如下:
關(guān)于這部分的解釋網(wǎng)上有很多,可以自行查閱。而我在開(kāi)發(fā)過(guò)程用的最多的就是
componentWillMount()
componentDidMount()
shouldComponentUpdate(nextProps, nextState)
這幾個(gè)鉤子函數(shù)了,關(guān)于性能優(yōu)化,可以在shouldComponentUpdate上作文章,由于shouldComponentUpdate默認(rèn)返回true,簡(jiǎn)單的方法可以通過(guò)比較更新前后的數(shù)據(jù)結(jié)構(gòu)是否相同來(lái)判斷組件是否需要重新渲染,這時(shí)候就可以采用immutable.js了。
組件之間通信react是單向數(shù)據(jù)流,自上而下的傳遞數(shù)據(jù)。解決復(fù)雜組件之間通信的方法有很多。一般父子組件通信是最簡(jiǎn)單的,父組件將一個(gè)回調(diào)函數(shù)傳遞給子組件,子組件通過(guò)this.props直接調(diào)用該函數(shù)與父組件通信。
如果組件之間嵌套很深,可以使用上下文getChildContext來(lái)傳遞信息,這樣在不需要將函數(shù)一層層往下傳,任何一層的子級(jí)都可以通過(guò)this.context直接訪問(wèn),react-redux內(nèi)部實(shí)現(xiàn)就是利用此方法。
兄弟組件之間無(wú)法直接通信,它們需要利用同一層的上級(jí)作為中轉(zhuǎn)站。
Reduxredux不是必須的,如果不是復(fù)雜的組件通信,邏輯簡(jiǎn)單,用context就行。redux并不是react特有的,其他框架也可以使用redux。當(dāng)初為了學(xué)習(xí)redux花費(fèi)了不少時(shí)間,一開(kāi)始并不理解redux中間的操作,看了很多前輩們寫(xiě)的文章才逐漸明白。簡(jiǎn)單說(shuō)說(shuō)redux。
redux由三部分組成:store, reducer, action
store是一個(gè)對(duì)象,它主要由三個(gè)方法:
dispatch
用于action的分發(fā),當(dāng)action傳入dispatch會(huì)立即執(zhí)行,有些時(shí)候我們不想它立刻觸發(fā),可以在createStore中使用middleware中間件對(duì)dispatch進(jìn)行改造,例如redux-thunk,不過(guò)這是react-radux做的事了。
subscribe
顧名思義,監(jiān)聽(tīng)器,監(jiān)聽(tīng)state的變化,這個(gè)函數(shù)在store調(diào)用dispatch時(shí)會(huì)注冊(cè)一個(gè)listener監(jiān)聽(tīng)state變化。
getState
獲取store中的state,當(dāng)我們用action觸發(fā)reducer改變了state時(shí),需要拿到新的state里面的數(shù)據(jù)。getState在兩個(gè)地方會(huì)用到,一是通過(guò)dispatch提交action后store需要拿到state里面的數(shù)據(jù),二是利用subscribe監(jiān)聽(tīng)到state發(fā)生變化后調(diào)用它來(lái)獲取新的state數(shù)據(jù)。
說(shuō)了這么多,store的核心代碼其實(shí)很短:
/** * 應(yīng)用觀察者模式 * @param {Object} state * @param {Function} reducer */ function createStore(reducer) { let state = null const listeners = [] const subscribe = listener => listeners.push(listener) const getState = () => state const dispatch = action => { // 覆蓋原對(duì)象 state = reducer(state, action) listeners.forEach(listener => listener()) } // 初始化state dispatch({}) return { getState, dispatch, subscribe } }
另一部分,reducer是一個(gè)純函數(shù)(pure function),它接收一個(gè)state和action作為參數(shù),根據(jù)action的type返回一個(gè)新的state,如果傳入的action type沒(méi)有匹配到,則返回默認(rèn)的state,簡(jiǎn)單實(shí)現(xiàn)如下:
function reducer(state, action) { if (!state) { return { title: { text: "water make redux", color: "red" }, content: { text: "water make redux", color: "green" } } } switch (action.type) { case "UPDATE_TITLE_TEXT": return { ...state, title: { ...state.title, text: action.text } } case "UPDATE_TITLE_COLOR": return { ...state, title: { ...state.title, color: action.color } } default: return state } }
action比較簡(jiǎn)單,它返回一個(gè)對(duì)象,其中type屬性是必須的,同時(shí)也可以傳入一些其他的數(shù)據(jù)。
使用例子如下:
/ 生成store const store = createStore(reducer) let oldState = store.getState() // 監(jiān)聽(tīng)數(shù)據(jù)變化重新渲頁(yè)面 store.subscribe(() => { const newState = store.getState() renderApp(newState, oldState) oldState = newState }) // 首次渲染頁(yè)面 renderApp(store.getState()) store.dispatch({ type: "UPDATE_TITLE_TEXT", text: "water is fighting" }) store.dispatch({ type: "UPDATE_TITLE_COLOR", color: "#f00" })React-redux
react-redux則是對(duì)redux做了封裝,可以在react中直接使用,并且提供了Provider和connect。
Provider是一個(gè)組件,它接受store作為props,然后通過(guò)context往下傳,這樣react中任何組件都可以通過(guò)context獲取store。
connect是一個(gè)函數(shù),也是一個(gè)高階組件(HOC),通過(guò)傳入state和dispatch返回一個(gè)新的組件,它的寫(xiě)法是如下:
connect(mapStateToProps, mapDispatchToProps, mergeProps, options)(component)
也可以采用裝飾器的寫(xiě)法,這需要babel的支持:
@connect( state, { func } )
具體的不多介紹,迷你實(shí)現(xiàn)可以看看這個(gè)項(xiàng)目:https://github.com/k-water/ma...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/107245.html
摘要:前言此項(xiàng)目是基于螞蟻金服開(kāi)源的之上,用全家桶的進(jìn)行再次開(kāi)發(fā)的,項(xiàng)目已經(jīng)開(kāi)源,項(xiàng)目地址在上。項(xiàng)目地址開(kāi)源不易,如果覺(jué)得該項(xiàng)目不錯(cuò)或者對(duì)你有所幫助,歡迎到上給個(gè),謝謝。 showImg(https://segmentfault.com/img/remote/1460000017116745); 前言 此 blog-react-admin 項(xiàng)目是基于 螞蟻金服開(kāi)源的 ant design p...
摘要:希望幫助更多的前端愛(ài)好者學(xué)習(xí)。前端開(kāi)發(fā)者指南作者科迪林黎,由前端大師傾情贊助。翻譯最佳實(shí)踐譯者張捷滬江前端開(kāi)發(fā)工程師當(dāng)你問(wèn)起有關(guān)與時(shí),老司機(jī)們首先就會(huì)告訴你其實(shí)是個(gè)沒(méi)有網(wǎng)絡(luò)請(qǐng)求功能的庫(kù)。 前端基礎(chǔ)面試題(JS部分) 前端基礎(chǔ)面試題(JS部分) 學(xué)習(xí) React.js 比你想象的要簡(jiǎn)單 原文地址:Learning React.js is easier than you think 原文作...
摘要:?jiǎn)雾?yè)博客應(yīng)用編寫(xiě)總結(jié)很久之前就想寫(xiě)一個(gè)博客應(yīng)用在一開(kāi)始想要直接用和模板直接寫(xiě)但是暑假一開(kāi)始的時(shí)候不小心入了的坑所以就一不做二不休直接用寫(xiě)那既然用了不寫(xiě)個(gè)單頁(yè)應(yīng)用也過(guò)意不去了不前前后后寫(xiě)了將近兩個(gè)星期現(xiàn)在看來(lái)這其實(shí)是一個(gè)很容易的應(yīng)用但是鑒于 React-Express單頁(yè)博客應(yīng)用編寫(xiě)總結(jié) 很久之前就想寫(xiě)一個(gè)博客應(yīng)用.在一開(kāi)始想要直接用express和ejs模板直接寫(xiě), 但是暑假一開(kāi)始的時(shí)...
閱讀 1698·2021-10-28 09:32
閱讀 604·2021-09-24 09:47
閱讀 2919·2021-09-02 15:11
閱讀 2731·2021-08-09 13:46
閱讀 2883·2019-08-30 15:55
閱讀 1070·2019-08-30 15:54
閱讀 3298·2019-08-29 14:12
閱讀 804·2019-08-26 13:40