- react遇到React.Fragment標籤,先驗證器檢測是否符合規範,再呼叫createElement建立reactElement。
- React.Fragment允許傳入的屬性有key,children,不能傳入ref以及其他屬性,因為React.Fragment最終不會渲染成一個真實DOM,所以ref引用到的是null,因此不能傳入ref作為屬性。
部分函式列表
getDeclarationErrorAddendum ------ 返回字串,內容為:檢查ReactCurrentOwner.current.type上的render方法
getSourceInfoErrorAddendum ------- 返回字串,內容為:檢查某個檔案下的某一行程式碼
getCurrentComponentErrorInfo ----- 錯誤提示,在ReactCurrentOwner.current不存在的時候,提示檢查parentType上的render
validateExplicitKey -------------- 對傳入的元件是否具有key進行錯誤處理
validateChildKeys ---------------- 對傳入的node中的每個element判斷是否存在key
validatePropTypes ---------------- 檢查propTypes的否大小寫正確,類元件或者函式元件設定預設prop只能用defaultProps,getDefaultProps只能用於React.createClass中
複製程式碼
validateFragmentProps
React.Fragment 也是通過createElement建立的。 React.Fragment 只能有key和children作為其屬性。 React.Fragment 特別注意不能傳入ref作為其屬性,因為React.Fragment不會渲染成一個真實的DOM,自然不會允許有ref。
<React.Fragment key111="Fragment 只能有key和children作為其屬性"
children111="Fragment 只能有key和children作為其屬性"
ref={{"some":"Fragment 也不能使用ref獲取引用"}}
key="允許的"
children="允許的,貌似沒什麼用,真實的children就是React.Fragment包裹的內容"
>
Some text.
<h2>A heading</h2>
</React.Fragment>
複製程式碼
createElementWithValidation
- 先檢查傳入的type是否是合法的element型別,見isValidElementType,如果不是丟擲錯誤
- 如果是則將type, props, children等引數傳入createElement生成對應的react元素
- 然後呼叫validateChildKeys對引數children的每個element判斷是否存在key
- 接著,如果type型別是REACT_FRAGMENT_TYPE,呼叫validateFragmentProps檢查Fragment上的屬性(這裡函式名為props不妥,key與ref不算是props中的,attributes比較好),其他type型別的元素的props的規則一致。
- 最後如果驗證成功,返回建立的element。
createFactoryWithValidation
工廠函式,對createElementWithValidation的封裝,返回一個函式,該函式用於建立一個element
export function createFactoryWithValidation(type) {
const validatedFactory = createElementWithValidation.bind(null, type);
validatedFactory.type = type;
return validatedFactory;
}
複製程式碼
cloneElementWithValidation
返回一個REACT_ELEMENT_TYPE型別的元素,其type屬性值為傳入的element,
export function cloneElementWithValidation(element, props, children) {
const newElement = cloneElement.apply(this, arguments);
for (let i = 2; i < arguments.length; i++) {
validateChildKeys(arguments[i], newElement.type);
}
//newElement為REACT_ELEMENT_TYPE型別,所以不許要判斷是否是REACT_FRAGMENT_TYPE型別
validatePropTypes(newElement);
return newElement;
}
複製程式碼
這個函式在開發環境下會作為React.cloneElement方法。而在生產環境下ReactElement.js中的cloneElement會作為React.cloneElement方法。
例1:children作為屬性
ReactDOM.render(
<React.Fragment children={["child","child","child"]}/>,
document.getElementById('app')
);
複製程式碼
例2:
let ReactFragment1 = React.cloneElement(<React.Fragment children={["child","child","child"]}/>,{xxx:"這會被新增到新元件的props上"})
console.log("ReactFragment1",ReactFragment1)
console.log("ReactFragment1",React.Fragment)
ReactDOM.render(
ReactFragment1,
document.getElementById('app')
);
複製程式碼