1. React入門
## 1.1. React基本認識 ## 1.2. React基本使用 ## 1.3. JSX的理解和使用 ## 1.4. 模塊與模塊化, 組件與組件化的理解
2. React組件化編程
## 2.1. 組件的定義與使用 ## 2.2. 組件的3大屬性: state, props, refs ## 2.3. 組件中的事件處理 ## 2.4. 組件的組合使用 ## 2.5. 組件收集表單數據 ## 2.6. 組件的生命週期 ## 2.7. 虛擬DOM與DOM diff算法 ## 2.8. 命令式編程與聲明式編程
1. React入門
1.1. React的基本認識
1). Facebook開源的一個js庫 2). 一個用來動態構建用戶界面的js庫 3). React的特點 Declarative(聲明式編碼) Component-Based(組件化編碼) Learn Once, Write Anywhere(支持客戶端與服務器渲染) 高效 單向數據流 4). React高效的原因 虛擬(virtual)DOM, 不總是直接操作DOM(批量更新, 減少更新的次數) 高效的DOM Diff算法, 最小化頁面重繪(減小頁面更新的區域)
1.2. React的基本使用
1). 導入相關js庫文件(react.js, react-dom.js, babel.min.js) 2). 編碼:
<div id="container"></div>
<script type="text/babel">
var aa = 123
var bb = 'test'
ReactDOM.render(<h1 id={bb}>{aa}</h1>, containerDOM)
</script>
1.3. JSX的理解和使用
1). 理解 * 全稱: JavaScript XML * react定義的一種類似於XML的JS擴展語法: XML+JS * 作用: 用來創建react虛擬DOM(元素)對象 2). 編碼相關 * js中直接可以套標籤, 但標籤要套js需要放在{}中 * 在解析顯示js數組時, 會自動遍歷顯示 * 把數據的數組轉換爲標籤的數組:
var liArr = dataArr.map(function(item, index){
return <li key={index}>{item}</li>
})
3). 注意: * 標籤必須有結束 * 標籤的class屬性必須改爲className屬性 * 標籤的style屬性值必須爲: {{color:'red', width:12}}
1.4. 幾個重要概念理解
1). 模塊與組件
1. 模塊: 理解: 向外提供特定功能的js程序, 一般就是一個js文件 爲什麼: js代碼更多更復雜 作用: 複用js, 簡化js的編寫, 提高js運行效率 2. 組件: 理解: 用來實現特定功能效果的代碼集合(html/css/js) 爲什麼: 一個界面的功能太複雜了 作用: 複用編碼, 簡化項目界面編碼, 提高運行效率
2). 模塊化與組件化
1. 模塊化: 當應用的js都以模塊來編寫的, 這個應用就是一個模塊化的應用 2. 組件化: 當應用是以多組件的方式實現功能, 這上應用就是一個組件化的應用
2. react組件化開發
2.1. 基本理解和使用
1). 自定義的標籤: 組件類(函數)/標籤 2). 創建組件類
//方式1: 無狀態函數(簡單組件, 推薦使用)
function MyComponent1(props) {
return <h1>自定義組件標題11111</h1>
}
//方式2: ES6類語法(複雜組件, 推薦使用)
class MyComponent3 extends React.Component {
render () {
return <h1>自定義組件標題33333</h1>
}
}
3). 渲染組件標籤
ReactDOM.render(<MyComp />, cotainerEle)
4). ReactDOM.render()渲染組件標籤的基本流程 React內部會創建組件實例對象/調用組件函數, 得到虛擬DOM對象 將虛擬DOM並解析爲真實DOM 插入到指定的頁面元素內部
2.2. 組件的3大屬性: state
1. 組件被稱爲"狀態機", 頁面的顯示是根據組件的state屬性的數據來顯示 2. 初始化指定:
constructor() {
super()
this.state = {
stateName1 : stateValue1,
stateName2 : stateValue2
}
}
3. 讀取顯示:
this.state.stateName1
4. 更新狀態-->更新界面 :
this.setState({stateName1 : newValue})
2.2. 組件的3大屬性: props
所有組件標籤的屬性的集合對象 給標籤指定屬性, 保存外部數據(可能是一個function) 在組件內部讀取屬性: this.props.propertyName 作用: 從目標組件外部向組件內部傳遞數據 對props中的屬性值進行類型限制和必要性限制
Person.propTypes = {
name: React.PropTypes.string.isRequired,
age: React.PropTypes.number.isRequired
}
擴展屬性: 將對象的所有屬性通過props傳遞
<Person {...person}/>
2.2. 組件的3大屬性: refs
組件內包含ref屬性的標籤元素的集合對象 給操作目標標籤指定ref屬性, 打一個標識 在組件內部獲得標籤對象: this.refs.refName(只是得到了標籤元素對象) 作用: 找到組件內部的真實dom元素對象, 進而操作它
2.3. 組件中的事件處理
1. 給標籤添加屬性: onXxx={this.eventHandler} 2. 在組件中添加事件處理方法 eventHandler(event) { } 3. 使自定義方法中的this爲組件對象 在constructor()中bind(this) 使用箭頭函數定義方法(ES6模塊化編碼時才能使用) 4. 事件監聽 綁定事件監聽 事件名 回調函數 觸發事件 用戶對對應的界面做對應的操作 編碼
2.4. 組件的組合使用
1)拆分組件: 拆分界面,抽取組件 2)實現靜態組件: 使用組件實現靜態頁面效果 3)實現動態組件 ① 動態顯示初始化數據 ② 交互功能(從綁定事件監聽開始)
2.5. 組件收集表單數據
受控組件 非受控組件
2.6. 組件的生命週期
1. 組件的三個生命週期狀態: Mount:插入真實 DOM Update:被重新渲染 Unmount:被移出真實 DOM 2. 生命週期流程:
* 第一次初始化顯示: ReactDOM.render(<Xxx/>, containDom)
constructor()
componentWillMount() : 將要插入回調
render() : 用於插入虛擬DOM回調
componentDidMount() : 已經插入回調
* 每次更新state: this.setState({})
componentWillReceiveProps(): 接收父組件新的屬性
componentWillUpdate() : 將要更新回調
render() : 更新(重新渲染)
componentDidUpdate() : 已經更新回調
* 刪除組件: ReactDOM.unmountComponentAtNode(div): 移除組件
componentWillUnmount() : 組件將要被移除回調
3. 常用的方法
render(): 必須重寫, 返回一個自定義的虛擬DOM
constructor(): 初始化狀態, 綁定this(可以箭頭函數代替)
componentDidMount() : 只執行一次, 已經在dom樹中, 適合啓動/設置一些監聽
2.7. 虛擬DOM與DOM diff算法
1). 虛擬DOM是什麼?
一個虛擬DOM(元素)是一個一般的js對象, 準確的說是一個對象樹(倒立的) 虛擬DOM保存了真實DOM的層次關係和一些基本屬性,與真實DOM一一對應 如果只是更新虛擬DOM, 頁面是不會重繪的
2). Virtual DOM 算法的基本步驟
用JS對象樹表示DOM樹的結構;然後用這個樹構建一個真正的DOM樹插到文檔當中 當狀態變更的時候,重新構造一棵新的對象樹。然後用新的樹和舊的樹進行比較,記錄兩棵樹差異 把差異應用到真實DOM樹上,視圖就更新了
3). 進一步理解
Virtual DOM 本質上就是在 JS 和 DOM 之間做了一個緩存。 可以類比 CPU 和硬盤,既然硬盤這麼慢,我們就在它們之間加個緩存:既然 DOM 這麼慢,我們就在它們 JS 和 DOM 之間加個緩存。CPU(JS)只操作內存(Virtual DOM),最後的時候再把變更寫入硬盤(DOM)。
2.8. 命令式編程與聲明式編程
聲明式編程 只關注做什麼, 而不關注怎麼做(流程), 類似於填空題 命令式編程 要關注做什麼和怎麼做(流程), 類似於問答題
var arr = [1, 3, 5, 7]
// 需求: 得到一個新的數組, 數組中每個元素都比arr中對應的元素大10: [11, 13, 15, 17]
// 命令式編程
var arr2 = []
for(var i =0;i<arr.length;i++) {
arr2.push(arr[i]+10)
}
console.log(arr2)
// 聲明式編程
var arr3 = arr.map(function(item){
return item +10
})
// 聲明式編程是建立命令式編程的基礎上
// 數組中常見聲明式方法
map() / forEach() / find() / findIndex()
1. 使用React腳手架創建一個React應用
1). react腳手架
1. xxx腳手架: 用來幫助程序員快速創建一個基於xxx庫的模板項目 * 包含了所有需要的配置 * 指定好了所有的依賴 * 可以直接安裝/編譯/運行一個簡單效果 2. react提供了一個專門用於創建react項目的腳手架庫: create-react-app 3. 項目的整體技術架構爲: react + webpack + es6 + babel + eslint
2). 創建項目並啓動
npm install -g create-react-app
create-react-app react-app
cd react-app
npm start
3). 使用腳手架開發的項目的特點
模塊化: js是一個一個模塊編寫的 組件化: 界面是由多個組件組合編寫實現的 工程化: 實現了自動構建/運行/打包的項目
4). 組件化編寫項目的流程
拆分組件 實現靜態組件--->靜態頁面 實現動態組件 動態顯示初始化數據 交互
2. app1: 實現一個評論管理功能
1). 拆分組件:
應用組件: App 添加評論組件: CommentAdd 評論項組件: CommentItem 評論列表組件: CommentList
2). 確定組件的state和props:
App:
* state: comments/array
CommentAdd
* state: username/string, content/string
* props: add/func
commentList
* props: comments/array, delete/func
CommentItem
* props: comment/object, delete/func, index/number
3). 編寫靜態組件
拆分頁面 拆分css
4). 實現動態組件
1. 動態展示初始化數據 * 初始化狀態數據 * 傳遞屬性數據 2. 響應用戶操作, 更新組件界面 * 綁定事件監聽, 並處理 * 更新state
3. app2: 實現github用戶搜索功能
1). react應用中的ajax請求
axios: 包裝XMLHttpRequest對象, promise風格, 支持瀏覽端/node服務器端 fetch: 瀏覽器內置語法, promise風格, 老瀏覽器不支持, 可以引入fetch.js兼容包
2). 拆分組件
App
* state: searchName/string
Search
* props: setSearchName/func
List
* props: searchName/string
* state: firstView/bool, loading/bool, users/array, errMsg/string
3). 編寫組件
編寫靜態組件 編寫動態組件 componentWillReceiveProps(nextProps): 監視接收到新的props, 發送ajax 使用axios庫發送ajax請求
4. 組件間通信總結
1). 方式一: 通過props傳遞
共同的數據放在父組件上, 特有的數據放在自己組件內部(state) 一般數據-->父組件傳遞數據給子組件-->子組件讀取數據 函數數據-->子組件傳遞數據給父組件-->子組件調用函數 問題: 多層傳遞屬性麻煩, 兄弟組件通信不方便
2). 方式二: 使用消息訂閱(subscribe)-發佈(publish)機制: 自定義事件機制
3). 事件監聽理解
1. DOM事件 * 綁定事件監聽 * 事件名(類型): 只有有限的幾個, 不能隨便寫 * 回調函數 * 用戶操作觸發事件(event) * 事件名(類型) * 數據 2. 自定義事件 * 綁定事件監聽 * 事件名(類型): 任意 * 回調函數: 通過形參接收數據, 在函數體處理事件 * 觸發事件(編碼) * 事件名(類型): 與綁定的事件監聽的事件名一致 * 數據: 會自動傳遞給回調函數
5. ES6新語法總結
定義變量/常量: const/let
解構賦值: let {a, b} = this.props import {aa} from 'xxx'
對象的簡潔表達: {a, b}
箭頭函數:
組件的自定義方法: xxx = () => {}
map/filter的回調方法: (item, index) => {}
優點:
* 簡潔
* 沒有自己的this,使用引用this查找的是外部this
擴展運算符: ...
拆解對象: const MyProps = {}, <Xxx {...MyProps}>
類: class/extends/constructor/super
ES6模塊化: export default | import
6. 項目打包運行
npm run build //生成打包文件
npm install -g serve //全局下載服務器包
serve build //通過服務器命令運行打包項目
訪問: http://localhost:5000 //瀏覽器訪問
1. redux要點
1. redux理解 2. redux相關API 3. redux核心概念(3個) 4. redux工作流程 5. 使用redux及相關庫編碼
#1. redux理解 什麼?: redux是專門做狀態管理的獨立第3方庫, 不是react插件 作用?: 對應用中狀態進行集中式的管理(寫/讀) 開發: 與react-redux, redux-thunk等插件配合使用
2. redux相關API
redux中包含: createStore(), applyMiddleware(), combineReducers()
store對象: getState(), dispatch(), subscribe()
react-redux: <Provider>, connect()()
3. redux核心概念(3個)
action:
默認是對象(同步action), {type: 'xxx', data: value}, 需要通過對應的actionCreator產生,
它的值也可以是函數(異步action), 需要引入redux-thunk纔可以
reducer
根據老的state和指定的action, 返回一個新的state
不能修改老的state
store
redux最核心的管理對象
內部管理着: state和reducer
提供方法: getState(), dispatch(action), subscribe(listener)
4. redux工作流程
5. 使用redux及相關庫編碼
需要引入的庫:
redux
react-redux
redux-thunk
redux-devtools-extension(這個只在開發時需要)
redux文件夾:
action-types.js
actions.js
reducers.js
store.js
組件分2類:
ui組件(components): 不使用redux相關PAI
容器組件(containers): 使用redux相關API