這陣子自己試著使用react做一個小小的網頁,遇到了一些頁面layout重複的狀況,或特定component需要複用的狀況,這個時候就讓我想到最近超常在Vue專案中使用的Slot,所以也就開始研究在React世界裡如何使用像Vue Slot一樣的方式靈活地重複使用元件。使用了這樣的方法後,使用到重複的部分,就不需要複製貼上,也能讓管理上更加便利,因為如果有調整,可以只改一個地方就全部使用的地方都被套用。

Vue世界的Slot
在正式開始前,先來回頭思考一下Vue世界的Slot該怎麼使用。
主要會需要以下幾個步驟:
1.  在需要被重複使用的子元件中,用slot標示會在父元件中依照當下情況或需求放入不同內容的地方。
2 . 在父元件中使用這個要被重複使用,且設定slot的子元件時,只需要在對應處放上當下情況要使用的內容,就會將內容擺放在slot指定的地方。(有種鑲嵌寶石到插槽的概念)
上面這兩個步驟是主要的大方向,更細節的具名插槽(Named Slot )、作用域插槽(Scoped Slot)內容可以參考這篇///


React世界的Slot
回顧完Vue的slot用法後,再來看看這次的主角,React世界的Slot!在React世界裡面,想要使用Vue Slot概念的用法的話,主要關鍵字會是children,使用方法也有差異,但一樣可以達到複用的目的,想要像Vue世界裡面使用具名的slot或是在特定slot中帶入prop也都是可以的。
在使用概念的部分,我自己的理解是「Vue的話,是在子元件中設定一個slot,再從父元件中,把要放入slot的內容帶入;React的話,則是用props的概念,帶入想要從父元件帶入子元件的內容,只是帶入的東西可能不是單純的值,而是HTML,或另一個元件。」


一般的children(單個slot)
如果子元件中,只會有一個插槽,在react中,只需要在父元件中將想要帶入子元件插槽中的東西寫在子元件中間(ex: <子元件>要插入的內容</子元件>),就可以在子元件中透過props.children取得於父層帶入的內容,如果想要有預設的內容,也可以透過三元表達式來達成。
範例
1. 在子元件中,透過props.chrildren取得要放在子元件的內容,並放在子元件中,並透過三元表達式來設定預設文字(如果父元件中,沒有另外帶入要放入子元件中的內容,就會使用預設內容)。
carbon (69)
2. 在父元件中,放入要使用的子元件,並在元件中間放入要帶入的內容。
carbon (67)
實際呈現結果
中間有文字的時候,按鈕顯示的是中間放入的文字,中間沒有放文字的時候,按鈕顯示的是預設文字。


具名插槽特性的children(多個slot)
如果想要在React世界中,想要在一個子元件中,設定不只一個slot的話,可以用指定名稱的props帶入。
範例:
1. 在子元件中,先把預計會用props帶入內容,依照名字放到預計要放入的位置,一樣能設定預設要顯示的內容。
這裡預計放在子元件裡面的內容分別是props.title、props.content。
carbon (54)
2. 在父元件中,使用這個子元件時,利用帶入props的方式,把要放入插槽的內容帶到子元件內。
carbon (55)
實際呈現結果
image
完整範例在這裡

*另外!除了帶入值以外,也可以帶入另一個component到slot裡面

其他實際範例
這裡我想要製作出一個可以利用slot概念,把父層資料擺在元件內的子元件。
子元件
子元件是一個Card 元件,分別有兩個地方會透過父層把資料放入。
carbon (56)
父元件
透過props傳入兩個位置個別需要的資料,讓子元件可以用props去接對應的資料。
carbon (57)
實際呈現結果

image
完整範例在這裡
在這個範例中,其實自己最深的感受就是在React世界,主要就是在使用props,讓元件被帶入對應的資料,跟Vue的slot真的有點不一樣。


自己比較過後的小小結論

簡單來說,就是一個是props,一個是真.slot。聽起來很像廢話,但真的就是props和slot,因為在Vue的世界,我覺得才是真正的slot XD
React主要是使用props的概念,所以整個思考流程自己覺得是偏向從外到內,也就是從父層到子層,而Vue則是偏向於在子元件上開一個或多個slot位置,並且在有多個slot位置時,需要在父層明確指出哪個欄位要放上指定的內容,感覺就偏向由內入外。其實使用起來,如果習慣Vue的用法,自己到React是有點轉不過來,但其實換個方向想,用使用props的方式去使用,反而覺得React的用法在某方面來說,反而更好理解,因為當初自己在熟悉Vue的slot內容的時候,也是轉不太過來,反而props的概念比較好懂,所以對於這部分的使用,其實React好像比較簡單(?)。

好啦! 這次小菜菜的筆記就差不多到這裡啦!
如果有理解錯誤的地方歡迎跟我說,有更好的理解方式也可以告訴我喔!
那就寫些打家囉!