react是一個js框架,能夠用它來編寫html頁面,使用react後咱們能夠徹底拋棄html(只須要一個主index文件),而用純js來編寫頁面;css
和直接用html編寫頁面相比,使用react有如下幾點好處:html
用html編寫頁面時,若是多個頁面擁有基本相同的模塊,那麼須要把相關模塊在各個html文件中所有複製一遍。而使用react咱們只須要把這些模塊寫成組件,在各個頁面中調用這個組件便可;前端
當信息發生改變時,須要從新渲染頁面,若是用html編寫,咱們須要花不少精力考慮架構問題,保證渲染效率;而react把這些問題封裝了起來,編寫高性能頁面會變得特別容易;react
當網站頁面變得複雜時,頁面管理將變得很是重要,咱們須要花不少精力在頁面架構和代碼維護上,而react 讓這一切變得簡單;web
react的目的是讓咱們更好的管理和複用代碼,若本身要編寫react組件,那麼基本的html標籤的應用,css語法都是必需要掌握的;使用react後咱們依然須要作如下兩點:算法
1. 親自編寫全部要渲染的頁面,雖然不用使用html,但須要用相似的 JSX語法。react只是幫咱們提升了複用性;redux
2. 親自寫全部的css代碼,頁面呈現效果依然須要本身分析編寫;瀏覽器
固然藉助不少開源的react組件,能夠取代一部分這些工做,不過作出的網站大都比較雷同,缺少個性;react-router
對前端稍微有點基礎的都知道,前端學習有3大塊html+css+js,其中咱們看到的全部web頁面的顯示效果只有兩個因素決定 ,即html和css;只要頁面發生了改變,不管是呈現的數據變了,圖表變了,圖片變了仍是某 個顏色變了,不管這種改變是如何致使的,好比鼠標點擊,聲音控制或者後臺數據改變。那麼必然意味着 html或者css發生了改變;簡而言之,頁面的呈現和html+css有着一一對應的關係;而前端的主要工做,除了 編寫各類頁面以外,就是使用js語言根據數據來不斷地更新html和css,從而使頁面發生變化;架構
當js以瀏覽器做爲宿主環境時,瀏覽器爲js提供了DOM做爲js操做文檔的惟一接口,當不使用任何框架時,要更新頁面,咱們必須親自調用DOM提供的API來更改文檔,效率極其低下;
在react中每一個組件都有一個state對象,它存儲了當前組件須要的全部可能發生變化的數據,渲染的html頁面和state中的數據是一種一一對應的關係。只要咱們經過setState方法改變了state中的數據,那麼html也 就跟着變化了,無需咱們親自動手修改dom;在使用react時,只要咱們根據state構建了組件,接下來只須要 考慮如何更新state便可。react爲更新dom提供了很是高效的算法,這裏不深刻展開去講了;
react組件的編寫須要兩類信息,變化的和不變的。在組件編寫時要花精力去分析哪些屬性在組件的生命週期 中是有可能發生變化的,哪些是不變的。不變的部分咱們就能夠寫死在html中,針對變化的部分其信息來源 有兩種 ,即組件的狀態和父組件的狀態;
在編寫組件時,要爲組件編寫一個state屬性,存儲了當前組件須要的數據;當須要改變狀態時,調用當前組件的this.setState()方法便可,瀏覽器會自動從新渲染當前組件,下面是官方demo的一個例子:
class Square extends React.Component { constructor() { super(); this.state = { value: null, }; } render() { return ( <button className="square" onClick={() => this.setState({value: 'X'})}> {this.state.value} </button> ); } }
當你遇到須要同時獲取多個子組件數據,或者兩個組件之間須要相互通信的狀況時,把子組件的 state 數據提高至其共同的父組件當中保存。以後父組件能夠經過 props 將狀態數據傳遞到子組件當中。這樣應用當中 的狀態數據就可以更方便地交流共享了。(官方文檔),官方示例以下:
1 //父組件 2 renderSquare(i) { 3 return ( 4 <Square 5 value={this.state.squares[i]} 6 onClick={() => this.handleClick(i)} 7 /> 8 ); 9 } 10 11 //子組件 12 class Square extends React.Component { 13 render() { 14 return ( 15 <button className="square" onClick={() =>this.props.onClick()}> 16 {this.props.value} 17 </button> 18 ); 19 } 20 }
小結:
state——組件的狀態屬性
setState——從新設置組件的狀態(這裏注意,須要設置一個新的對象而不是在原有組件對象上作修改,至於緣由,官方文檔上說的很清楚)
props——子組件經過這個屬性得到父組件的信息
redux是一個用來管理前端數據的一個架構,只有在應用程序很是複雜,數據來源複雜,交互頻繁的狀況下, 應用redux纔有明顯的好處;好比,某個應用有上百個組件,而且組件之間信息交互頻繁,若是不使用redux ,那麼數據將會分散在上百個組件當中,而且當多個組件須要同一個數據時,一樣的數據在每一個組件中將有 一個副本,當數據改變時,維護起來會至關麻煩。這種狀況下就須要考慮引入redux;
(1) 單一數據源
使用redux的程序,全部的state都存儲在一個單一的數據源store內部,相似一個巨大的對象樹。
(2)state是隻讀的
state是隻讀的,能改變state的惟一方式是經過觸發action來修改
(3)使用純函數執行修改
爲了描述 action 如何改變 state tree , 你須要編寫 reducers。reducers是一些純函數,接口是當前state和action。只須要根據action,返回對應的state。並且必需要有返回。
store=createStare(reducer)——建立store
state=store.getState()
store.dispatch(action)——觸發action,這是改變state的惟一接口
store.subscribe(listener)——一旦State發生變化,就自動執行這個函數,只要把 View 的更新函數(對於 React 項目,就是組件的render方法或setState方法)放入listen,就會實現 View 的自動渲染。
Redux 提供了一個combineReducers方法,用於 Reducer 的拆分。你只要定義各個子 Reducer 函數,而後用這個方法,就能夠將它們合成一個大的 Reducer。
爲了方便使用,Redux 的做者封裝了一個 React 專用的庫 React-Redux;React-Redux 將全部組件分紅兩大 類:UI 組件(presentational component)和容器組件(container component),其中UI組件,是「純組件」,只負責呈現,全部數據經過props獲取;容器組件負責數據和邏輯。可使用裝飾器模式把純組件轉化 爲容器組價,這裏主要用到了三個函數:
創建一個從(外部的)state對象到(UI 組件的)props對象的映射關係。
用來創建store.dispatch方法到props對象的映射。
React-Redux 提供connect方法,用於從 UI 組件生成容器組件。它須要mapStateToProps和mapStateToProps做爲參數。例如:
const VisibleTodoList = connect(
mapStateToProps,
mapDispatchToProps
)(TodoList)
<Provider> 組件
當組件嵌套比較深的時候,內層組件要得到state會很是麻煩,須要藉助props屬性一層一層傳遞。Proveder組件解決了這個問題,把Provider組件放在最外層,只要在Proveder上傳入store,這樣全部子組件均可以拿到state了
1 render( 2 <Provider store={store}> 3 <App /> 4 </Provider>, 5 document.getElementById('root') 6 )
一個應用程序每每不僅一個頁面,在多頁面應用程序中咱們須要在各個頁面之間切換,react-route架構提供了在多個頁面和組件之間進行切換的機制;react-router經常使用組件以下:
<BrowserRouter>
<Link>
爲你的應用提供聲明式的、可訪問的導航連接。
--屬性 to
<Route>
最基本的職責是在其 path 屬性與某個 location 匹配時呈現一些 UI。
--屬性 path
--屬性 component
--exact徹底匹配
<Switch>
只渲染命中的第一個路由
<Redirect>
直接渲染路由
--屬性 to