摘要:無狀態組件除了可以通過來創建組件以外,組件也可以通過一個普通的函數定義,函數的返回值為組件渲染的結果。這就是為什么要有屬性,屬性能夠幫助定位與數組元素的關系,在重渲染的時候能夠實現渲染優化。
1.3 React 組件 1.3.1 React 組件介紹書籍完整目錄
在 React 中組件是第一元素,是 React 的基礎,一個 React 應用就是基于 React 組件的組合而成。
前面的 JSX 練習過后,大家應該對 React 組件不陌生了,在這一節我們將溫習以及深入學習 React 組件。
創建一個 React 組件的方法為,調用 React.createClass 方法,傳入的參數為一個對象,對象必須定義一個 render 方法,render 方法返回值為組件的渲染結構,也可以理解為一個組件實例(React.createElement 工廠方法的返回值),返回值有且只能為一個組件實例,或者返回 null/false,當返回值為 null/false 的時候,React 內部通過 標簽替換。
eg:
var MyComponent = React.createClass({ render: function() { return組件命名空間....
; } });
可以看出 React.createClass 生成的組件類為一個 Javascript 對象。 當我們想設置命名空間組件時,可以在組件下面添加子組件:
eg:
MyComponent.SubComponent = React.createClass({...}); MyComponent.SubComponent.Sub = React.createClass({....});
在組件較多的情況下,可以借助命名空間優化組件維護結構以及解決組件名稱沖突問題。
無狀態組件除了可以通過 React.createClass 來創建組件以外,組件也可以通過一個普通的函數定義,函數的返回值為組件渲染的結果。
eg:
function StatelessComponent(props) { returnHello {props.name}}
無狀態組件能夠優化性能,因為其內部不會維護狀態,React 內部不會有一個對應的組件實例,并且也沒有生命周期 hook。
1.3.3 將組件渲染到 DOM 中當創建好了組件過后,為了將組件渲染到 DOM 中顯示出來,需要兩個步驟
在 HTML 中定義一個元素,設置 id 屬性
JSX 中調用 ReactDOM.render 方法, 第一個參數為 組件,第二個為剛才定義的 DOM 元素
eg:
對于組件的渲染,可能涉及到的一些問題:
Q1: 只能 render 到一個元素嗎?
Q2: 在程序運行時能夠動態的調用 render 嗎?
Q3: 修改了數據過后,還需要重新調用 render 方法嗎?
這里要先提一下 React 的設計初衷,React 在開發時候的目標就是簡單精巧,可以和其他框架結合起來使用。簡單而言我們可以當 React 是一個渲染數據對象到 DOM 中的 Javascript 函數工具類,工具類當然可以多次使用。
那么對于上面的問題:
A1: 不是,React 可以渲染到多個元素,任意位置的元素。
A2: 可以,比如以一個彈出層組件為例,我們希望創建一個 append 到 body 最后的組件來實現全屏遮罩, 那么我們可以動態的創建一個 div append 到 body 最后,然后將彈出層 render 到那個 div 內。
A3: 假設每次數據改變都重新調用 render 方法,那么每次 render 帶來的結果是重新創建一個頂級組件實例,以及子組件實例。 如果只調用 render 一次,將數據的變更放在組件內部,那么就不會重復創建頂級組件。
1.3.4 組件狀態 StateReact 中每個組件可以存儲自己的當前狀態, 以一個 switch 開關組件為例,開關的狀態可以存儲在組件內部。
React 的渲染結果是由組件屬性和狀態共同決定的,狀態和屬性的區別是,狀態維護在組件內部,屬性是由外部控制,我們先介紹組件狀態相關細節:
控制狀態的 API 為:
this.state:組件的當前狀態
getInitialState:獲取組件的初始狀態,在組件加載的時候會被調用一次,返回值賦予 this.state 作為初始值
this.setState:
組件狀態改變時,可以通過 this.setState 修改狀態
setState 方法支持按需修改,如 state 有兩個字段,僅當 setState 傳入的對象包含字段 key 才會修改屬性
每次調用 setState 會導致重渲染調用 render 方法
直接修改 state 不會重渲染組件
eg:
var Switch = React.createClass({ // 定義組件的初始狀態,初始為關 getInitialState: function() { return { open: false } }, // 通過 this.state 獲取當前狀態 render: function() { console.log("render switch component"); var open = this.state.open; return }, // 通過 setState 修改組件狀態 // setState 過后會 React 會調用 render 方法重渲染 toggleSwitch: function() { var open = this.state.open; this.setState({ open: !open }); } })1.3.5 組件屬性 Props
前面已經提到過 React 組件可以傳遞屬性給組件,傳遞方法和 HTML 中無異, 可以通過 this.props 獲取組件屬性
屬性相關的 API 為:
this.props: 獲取屬性值
getDefaultProps: 獲取默認屬性對象,會被調用一次,當組件類創建的時候就會被調用,返回值會被緩存起來,當組件被實例化過后如果傳入的屬性沒有值,會返回默認屬性值
this.props.children:子節點屬性
propTypes: 屬性類型檢查
以一個代辦事項的列表項組件為例:
// props.name 表示代辦事項的名稱 var TodoItem = React.createClass({ render: function() { var props = this.props; returnchildren 屬性{props.name}} }); ReactDOM.render(, document.getElementById("example"));
組件屬性中會有一個特殊屬性 children ,表示子組件, 還是以上面一個組件為例子,我們可以換一種方式定義 name:
var TodoItem = React.createClass({ render: function() { var props = this.props; return{props.children}} }); ReactDOM.render(代辦事項1 , document.getElementById("example"));
屬性類型檢查需要注意的是,children 只能為一個元素,不能為多個組件
為了保證組件傳遞屬性的正確性, 我們可以通過定義 propsType 對象來實現對組件屬性的嚴格校驗:
var MyComponent = React.createClass({ propTypes: { optionalArray: React.PropTypes.array, optionalBool: React.PropTypes.bool, optionalFunc: React.PropTypes.func, optionalNumber: React.PropTypes.number, optionalObject: React.PropTypes.object, optionalString: React.PropTypes.string, // 任何可以被渲染的包括,數字,字符串,組件,或者數組 optionalNode: React.PropTypes.node, // React 元素 optionalElement: React.PropTypes.element, // 枚舉 optionalEnum: React.PropTypes.oneOf(["News", "Photos"]), // 任意一種類型 optionalUnion: React.PropTypes.oneOfType([ React.PropTypes.string, React.PropTypes.number, React.PropTypes.instanceOf(Message) ]), // 具體類型的數組 optionalArrayOf: React.PropTypes.arrayOf(React.PropTypes.number), // 具體類型的對象 optionalObjectOf: React.PropTypes.objectOf(React.PropTypes.number), // 符合定義的對象 optionalObjectWithShape: React.PropTypes.shape({ color: React.PropTypes.string, fontSize: React.PropTypes.number }), requiredFunc: React.PropTypes.func.isRequired, requiredAny: React.PropTypes.any.isRequired, // 自定義校驗 customProp: function(props, propName, componentName) {} } });屬性傳遞的單向性
我們已經提到過 React 的單向數據流模式,數據的流動管道就是 props,流動的方向就是組件的層級自定向下的方向。所以一個組件是不能修改自身的屬性的,組件的屬性一定是通過父組件傳遞而來(或者默認屬性)。
無狀態組件屬性對于無狀態組件,可以添加 .propTypes 和 .defaultProps 屬性到函數上。
1.3.6 組件的嵌套組合在 1.2 節的 JSX 實例子中,當我們循環輸出 todo 列表的時候,React 會提示對于循環輸出的組件,需要有一個唯一的 key 屬性。這個問題的原因在于 React 的調和機制(Reconciliation)上。
什么叫調和?在每次數據更新過后,React 會重新調用 render 渲染出新的組件結構,新的結構應用到 DOM 中的過程就叫做調和過程。
為什么需要調和?想一想,假設我們有一個輸入組件,這個時候我們正聚焦在輸入框中,當修改值過后觸發事件導致了數據改變,數據改變導致了重渲染, 這個時候輸入框被替換成了新的 DOM。 這個過程對用戶來說應該是無感知的,所以那原來的聚焦狀態應該被保存, 那怎么做到的呢? DOM 都被替換了,輸入狀態,選擇狀態為什么還能保存。 我們先不急著知道 How,目前只需要知道這就是調和過程,后面我們會在 React 實現原理章節進行詳細介紹。
除了保存狀態以外,調和過程還做了很多 DOM 優化。 比如輸出一個數組的時候,數據新增加或者減少了一下,或者數組項值改變了,實際上我們沒有必要刪除原來的 DOM 結構,只需要修改 DOM 的值或者刪除 DOM 就能實現重渲染。
這就是為什么要有 key 屬性,key 屬性能夠幫助定位 DOM 與數組元素的關系,在重渲染的時候能夠實現渲染優化。
1.3.7 實例練習:通過組件化的方式優化之前的待辦事項列表 問題優化 JSX 語法練習的 TODOMVC 頁面, 通過組件化的方式拆分頁面!
組件如下:
App 組件:整個頁面的最完成組件
Header 組件:頭部輸入組件
TodoList 組件:列表組件
TodoItem 組件: 列表項
Footer 組件:底部操作組件
Tips循環輸出組件的方式
方式一:先計算出組件
function render() { var todos = this.props.todos; var $todos = todos.map(function(todo) { return}); return {$todos}}
方式二:{} 內直接計算
function render() { var todos = this.props.todos; return參考答案{todos.map(function(todo) { return}})}
https://github.com/leanklass/leanreact/tree/component
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/54335.html
摘要:無狀態組件除了可以通過來創建組件以外,組件也可以通過一個普通的函數定義,函數的返回值為組件渲染的結果。這就是為什么要有屬性,屬性能夠幫助定位與數組元素的關系,在重渲染的時候能夠實現渲染優化。 書籍完整目錄 1.3 React 組件 showImg(https://segmentfault.com/img/bVvLOW); 1.3.1 React 組件介紹 在 React 中組件是第一元...
書籍完整目錄 4.1 react 代碼規范 showImg(https://segmentfault.com/img/bVyE9m); 關于 基礎規范 組件結構 命名規范 jsx 書寫規范 eslint-plugin-react 關于 在代碼的設計上,每個團隊可能都有一定的代碼規范和模式,好的代碼規范能夠提高代碼的可讀性便于協作溝通,好的模式能夠上層設計上避免不必要的 bug 出現。本節會參考...
摘要:需要提醒讀者的是,的很多例子都是通過來寫的,但這并不是語法,后面我們會有單獨的一小節講解的基本語法,不過目前為止我們先將跟多精力放在上。 書籍完整目錄 1.2 JSX 語法 showImg(https://segmentfault.com/img/bVvKLR); 官方文檔 https://facebook.github.io/react/docs/jsx-in-depth.html ...
摘要:單向數據流應用的核心設計模式,數據流向自頂向下我也是性子急的人,按照技術界的慣例,在學習一個技術前,首先得說一句。然而的單向數據流的設計讓前端定位變得簡單,頁面的和數據的對應是唯一的我們可以通過定位數據變化就可以定位頁面展現問題。 書籍完整目錄 1.1 React 介紹 showImg(https://segmentfault.com/img/bVvJgS); 1.1.1 React ...
閱讀 3454·2021-11-22 12:00
閱讀 671·2019-08-29 13:24
閱讀 2905·2019-08-29 11:31
閱讀 2587·2019-08-26 14:00
閱讀 3185·2019-08-26 11:42
閱讀 2476·2019-08-23 18:31
閱讀 798·2019-08-23 18:27
閱讀 2844·2019-08-23 16:58