摘要:于是考慮通過直接對進行修改屬性的方法來達到我們的目的,修改組件。運行后驚呆了,報錯了意思是說屬性是不能擴展的,即不能修改。于是,嘗試修改代碼如下運行之后,成了當然擴展的話可以根據(jù)判斷或者其他要求來相應的修改屬性,此處統(tǒng)一將所有的變?yōu)榧t色。
React入門,大神輕噴哈^_^
下面的代碼是建立在React 0.14.*版本的
今天在嘗試封裝React component的時候碰到了幾個問題,猜小白們學習React中可能會碰到,我就整理下希望能幫助到小白們。
Keyword: props children cloneElement
React父子組件交流一般是用props傳遞,比如:
const T = React.createClass({ render() { return{ this.props.text }
} }); const B = React.createClass({ render() { return () } }); ReactDOM.render( , document.querySelector("#container"));
運行后自然是輸出下面兩行啦
level A
level B
上面栗子中有兩個子組件包含在
這時候就需要利用this.props的一個重要屬性了:children。
const C = React.createClass({ render() { return () } }); const D = React.createClass({ render() { return( lever C
lever D
{ this.props.children }) } }); ReactDOM.render(, document.querySelector("#container"));
這里this.props.children會獲得傳入的兩個React element
重要的問題來了,那如何控制傳入的elements咧?總不能你給我什么就呈現(xiàn)什么吧,比如上面的栗子中我就想把傳入的元素統(tǒng)統(tǒng)變成紅色字體,怎么做?
給外層div加個ref,如 X , 然后利用this.refs.X.style.color = "#f00"。這種做法只能勉強滿足當前做法,很不靈活,一旦要修改的樣式子級無法繼承就沒用了,所以不可取。
給外層div加個className如 cl ,接著在樣式文件中寫明.cl h1 的樣式。這種做法比上一種方案好一點,但是缺點是只能應付樣式,并且需要在已知children的標簽類型才行。但假設需求就是給children的所有的文本類標簽添加紅色樣式,但不說明用的是
是否可以直接遍歷this.props.children進而修改屬性呢?
舉上面栗子,輸出的this.props.children,展開后會發(fā)現(xiàn):組件在React中是以一個對象的形式存在,包含了type, ref 和 Key 屬性,還有最重要的props屬性。
props包含了除前邊三個之外的寫在組件上的其他屬性,包括默認屬性src / alt這些,還有自定義的如這里的wen屬性。
!這里注意的是props中不包含{ref,key},下面會提及到。
于是考慮通過直接對props進行修改屬性的方法來達到我們的目的,修改D組件。
const D = React.createClass({ render() { let children = this.props.children.map( (o, i)=>{ o.props.style = { color: "#f00" }; return o; }); return ({ children }) } });
運行后驚呆了,報錯了:
Uncaught TypeError: Can"t add property style, object is not extensible
意思是說props屬性是不能擴展的,即不能修改。
后面繼續(xù)嘗試給o增刪屬性都是會報錯,說明這里遍歷的每個對象o都是read only的。
醉了。。。這還怎么達到我們的目的咧?
于是乎繼續(xù)回頭翻閱React官方文檔,瞄到了React.cloneElement,突然意識到了什么,沒錯,正面太鋒芒,我們繞開它,直接修改對象不行,我們就拷貝一個自己用。
ReactElement cloneElement( ReactElement element, [object props], [children ...] )
這里的element是我們要拷貝的原對象,在這里是o。
props可選,當傳入個對象的時候是會和原對象的props進行合并,合并的方式是無則添加,有則覆蓋。
children就是前邊提到的props.children,用來加入子組件的,也是可選,這個栗子中暫時用不到。
于是,嘗試修改代碼如下:
const D = React.createClass({ render() { let children = this.props.children.map( (o, i)=>{ return React.cloneElement(o, { style: {color:"#f00"} }) }); return ({ children }) } });
運行之后,成了!!!
當然擴展的話可以根據(jù)判斷o.type或者其他要求來相應的修改屬性,此處統(tǒng)一將所有的
不過到這里還沒結束,雖然效果有了,但是在console中還是出現(xiàn)了警告:
Warning: Each child in an array or iterator should have a unique "key" prop. Check the render method of D. It was passed a child from C.
這個好理解,就是在遍歷數(shù)組的時候需要給每個元素添加Key屬性。不過問題來了,前邊說,key不算是Props的一員,即不能通過o.props.key=...來添加key。看React.cloneElement的參數(shù)列表中只有element, props和children,我又醉了,這次文檔也沒幫到什么了。
于是乎,看看源碼cloneElement的源碼,不看不知道,一看想給文檔一巴掌,誤導我了!
是不是恍然大悟了?沒錯,雖然參數(shù)名是叫Props,不過實際上React是把ref/key這些屬性也當成Porps的一部分(報錯的信息里邊也確實說"key" prop),只是在保存的時候會多帶帶拿出來,為了和其他屬性區(qū)分開。
在clone的過程中,對props的遍歷會先多帶帶把ref和key拿出來判斷,并且不會保存在新的Props中,也就在輸出的時候看到的是分離的。
不過,既然clone的時候props參數(shù)包含著Key,那就容易了,修改一行代碼如下。
const D = React.createClass({ render() { console.log(React.cloneElement); // 這里需要注意如果this.props.children只有一個元素,那將不是一個數(shù)組, // 所以還是需要提前判斷類型,用Array.isArray(this.props.children) let children = this.props.children.map( (o, i)=>{ return React.cloneElement(o, { style: {color:"#f00"}, key: i }) }); return ({ children }) } });
完成!!!
另外,React還提供了關于React.children的幾個有用的頂層API,也很有用,這里就不說了,具體的參考官方文檔哈。
https://facebook.github.io/react/docs/top-level-api.html#react.children
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/78603.html
摘要:倘若在之后修改對象屬性,會有兩種結果若在非下,不會報錯,但是任何修改都是不起作用的。總結開發(fā)過程中還是用非壓縮版的好,有利于及時發(fā)現(xiàn)問題。 在 React - 修改children(上) 中我提到了React在遍歷children過程中是不允許修改其中的React Element的,這里我要做點補充,就是有個前提是:使用的React是非壓縮版的,也就是說不是使用react.min.js...
摘要:使用者需要做的,就是完成回調函數(shù)里的邏輯即可,十分簡單。如果你需要異步生成,你需要設置參數(shù)為元素展現(xiàn)時的回調函數(shù),接收和作為參數(shù)。多次展現(xiàn)時,是否每次都觸發(fā)回調函數(shù)組件里監(jiān)聽滑動事件時,用了。 showImg(https://segmentfault.com/img/bVbloJf?w=620&h=480); 寫在前面 在這個數(shù)據(jù)無比重要的時代,用戶在網(wǎng)頁上面的一系列操作,都需要用數(shù)據(jù)...
摘要:每當?shù)闹蹈淖兒螅覀冎恍枰匦抡{用方法即可現(xiàn)在,讓我們來實現(xiàn)一個類似風格的歸約函數(shù),以不斷的遞增。歸約函數(shù)是不允許修改當前狀態(tài)的,所有最簡單的實現(xiàn)方式就是。 原文:Functional Components with React stateless functions and Ramda 閱讀本文需要的知識儲備: 函數(shù)式編程基本概念(組合、柯里化、透鏡) React 基本知識(組件、...
摘要:組件有兩個關鍵的表明當前是否應高亮,自己被點擊時調用的回調函數(shù),由于是每個頁面的容器,它只負責把渲染出來,所以用函數(shù)式組件即可。 這種模式本質上解決的是組件之間傳值的問題。但是它對于傳值以及一些內部操控的邏輯封裝得更嚴密。 場景:希望減少上下級組件之間props的傳遞,簡單來說就是不用傳做顯式地傳值,來達到組件之間相互通信的目的 舉例來說,某些界面中應該有Tabs這樣的組件,由Tab和...
摘要:近兩年來一直在關注開發(fā),最近也開始全面應用。首先,我們從無狀態(tài)組件開始。渲染回調模式有一種重用組件邏輯的設計方式是把組件的寫成渲染回調函數(shù)或者暴露一個函數(shù)屬性出來。最后,我們將這個回調函數(shù)的參數(shù)聲明為一個獨立的類型。 近兩年來一直在關注 React 開發(fā),最近也開始全面應用 TypeScript 。國內有很多講解 React 和 TypeScript 的教程,但如何將 TypeScri...
閱讀 3361·2021-11-11 16:54
閱讀 3511·2021-10-11 10:58
閱讀 1258·2021-08-30 09:41
閱讀 1807·2019-08-30 15:54
閱讀 2029·2019-08-30 14:00
閱讀 2700·2019-08-29 17:13
閱讀 1667·2019-08-29 15:19
閱讀 611·2019-08-29 15:14