styled-components —— React 中的 CSS 最佳實踐
https://zhuanlan.zhihu.com/p/29344146
Styled-components 是目前 React 樣式方案中最受關注的一種,它既具備了 css-in-js 的模塊化與參數化優點,又完全使用CSS的書寫習慣,不會引起額外的學習成本。本文是 styled-components 作者之一 Max Stoiber 所寫,首先總結了前端組件化樣式中的最佳實踐原則,然后在此基礎上介紹了 styled-components 的設計理念:“強制你使用組件化樣式的最佳實踐”。本文對于前端組件、樣式的實踐原則等很有啟發性,同時本人也十分推薦 styled-components 這一方案。
原文鏈接:Styled Components: Enforcing Best Practices In Component-Based Systems
歡迎關注本人知乎專欄:熵與單子的代碼本
在 web 中構建用戶交互是很困難的,因為 web 和其中的 CSS 最初是為文檔設計的。一些聰明的開發者發明了諸如 BEM 、ITCSS 、 SMACSS 的方法或規范,通過使用組件使得構建用戶交互更為簡單和可維護。
當我們的觀念轉變為構建組件化用戶交互后,就步入了所謂的“組件時代“。React 、 Ember 以及最近的Angular 2 等JavaScript框架的崛起、W3C為標準化web原生組件系統做出的努力、模式庫與設計規范被認為是構建web應用的正確方式,這種種的事件都表明這一變革正在發生。
const Button = styled.a`
/* This renders the buttons above... Edit me! */
display: inline-block;
border-radius: 3px;
padding: 0.5rem 0;
margin: 0.5rem 1rem;
width: 11rem;
background: transparent;
color: white;
border: 2px solid white;
/* The GitHub button is a primary button
* edit this to target it specifically! */
${props => props.primary && css`
background: white;
color: palevioletred;
`}
`
一個使用 styled-components 的 React 組件
組件化系統中的最佳實踐
隨著我們構建的組件化應用越來越多,我們總結了一些最佳實踐。今天我想討論其中最主要的三條:使用小型、功能單一、獨立的組件;分離容器組件與展示性組件;使用唯一的 CSS 類名。
小型化組件
使用組件來組織應用比使用CSS類更有優勢。例如,想象有一個 Button 組件在 DOM 中渲染 <button class="btn"> 。另外也可以渲染一個更大更重要的按鈕。創建一個更大的按鈕可以簡單的在 DOM 中添加 btn--primary 類: <button class="btn btn--primary"> 。
如果不想要求組件的使用者必須具體知道要添加哪個類,可以給 Button 組件添加 primary 屬性。這樣創建一個基本按鈕將只需簡單的: <Button primary /> !以下是實現方式:
// Button.js
function Button(props) {
const className = `btn${props.primary ? ' btn—-primary' : ''}`
return (
<button className={className}>{props.children}</button>
);
}
現在,使用者就不需要知道它具體應用了哪個類;他們只需要渲染一個基本按鈕。當設置參數 primary 之后發生了什么屬于組件的實現細節。改變這個按鈕的樣式、類或者行為只需要編輯創建組件的那一個文件,而不用改變使用它的上百個文件。
分離容器組件與展示性組件
在 React 中,某些組件可能具有 state 。試著分離處理數據、邏輯(比如數據格式化)的組件與處理樣式的組件。通過分離這兩者,追溯代碼中的變化將會簡便很多。
如果后端 API 格式改變了,你所要做的只是進入你的容器組件,確保在新數據格式下渲染與之前相同的展示性組件,這樣一切都會運行完好。
另一方面,如果 APP 的視覺設計或用戶體驗需要更改,你所要做的只是進入你的展示性組件并確保他們自身能正確顯示。由于這些組件并不關注它們在何時何處被渲染,你也沒有改變渲染哪個組件,一切都會運行完好。
通過區分這兩種類型的組件,你就不需要同時進行多個不相關聯的更改,這避免了意外錯誤。
使用唯一類名
回到我們的 Button 組件,他有一個 .btn 類。改變這個類的樣式應該只影響 Button 。如果在我的 .btn 類中改變 background-color 搞亂了 header 的布局并使得 footer 從三列變為了兩列,那肯定出問題了。這違背了整個使用獨立組件的前提。
這從根本上要求了所有類在CSS中只能使用了一次(在類似 .clearfix 的“ mixins “之外)。這樣,類似上文中的 bug 就永遠不會發生了。
問題其實一直出在人上面。程序中遇到 bug 了?它出現是因為有人把它寫在那里了。如果程序能夠脫離人而存在,那 bug 不會成為一個問題。你遇到和修改的每個 bug 都是由人的錯誤造成的。
在前端圈有一個有名的笑話:
兩個 CSS 參數走進一家酒吧( bar ),另一家酒吧的凳子就倒了。
這個笑話如此廣為流傳,就說明了太多開發者曾經遇到過這種類型的 bug 。不管你多努力地去避免,它總是發生,特別是在團隊中。
考慮到這種種事情,Glen Maddern 和我開始坐下來考慮新時代的樣式。我們并不想重新發明或者拋棄 CSS ;它是為樣式而造的語言并且瀏覽器原生支持。相反,讓我們利用 CSS 中最好的部分,并且讓組件化的系統中幾乎不再有人為的錯誤。
執行最佳實踐
Styled-components 最基本的理念就是通過移除樣式與組件之間的對應關系來強制執行最佳實踐。回想一下你使用過的任何樣式方法,樣式片段與 HTML 之間總是有一個對應關系。
在標準 CSS 中,這會是一個類名(或者也許是一個 ID )。在 React 的 styles in JavaScript 庫中,這是通過一個變量設置一個類或給 style 屬性傳遞一個 JavaScript 對象。
由于我們對每個類只想使用一次,不如直接移除這種對應關系如何?
結果證明,通過這種方式,我們還強制了容器組件與展示性組件的分離,而且我們也確保了開發者只能構建小型而單一的組件。
Styled-components 另一個有趣的特性是他讓你在 JavaScript 中寫真 CSS (而不僅僅是類似 CSS 的 JavaScript 對象)。它利用了 ECMAScript 2015 (新版的 JavaScript 標準)中一個不太常用的特性,稱為標簽模板字面量(譯者注:先前ES版本中稱為模板字符串),使得開發者有良好的使用體驗。
基本用法
現在,你一定想知道它長什么樣。那讓我們來看一看!
const Title = styled.h1`
color: palevioletred;
font-size: 1.5em;
text-align: center;
`;
你可以和其他 React 組件一樣地去使用它:
<Wrapper>
<Title>Hello World, this is my first styled component!</Title>
</Wrapper>
以上組件在瀏覽器中的顯示效果
這里面的內容不多,所以讓我們解讀一下這段代碼。
styled.h1 是一個函數,當調用時返回一個 React 組件,將一個 h1 渲染到 DOM中。你可能會好奇:“我們在哪里調用那個函數了?我只看到反引號,沒有括號!”,這正是 ECMAScript 2015 特性起作用之處。
以上你看到的是一個標簽模板字面量,是 JavaScript 語言的新特性。(使用 styled-components 不需要特別的工具)你可以使用反引號(如 styled.h1`` )調用函數,并且他們會接受傳入的字符串作為第一個參數。隨著我們深入,你會看到它與正常通過括號調用函數有何不同,但是現在我們先這樣放一放。
所以,這里調用 styled.h1 返回了一個 React 組件。這個 React 組件被添加了一個類,這個類由 styled-components 自動生成并確保唯一。這個類名將會關聯有你傳入模板字面量的樣式。
總之,這意味著調用 styled.h1 返回了一個 React 組件,它具有你傳入模板字面量的樣式。
完全支持 CSS
由于 styled-components 就是 CSS ,它很好的支持所有的 CSS。媒體查詢、偽選擇器、甚至嵌套都可以。我們生成一個類名,然后將 CSS 注入到 DOM ;所以任何在 CSS 中適用的,在 styled-components 中同樣適用。
const Input = styled.input`
font-size: 1.25em;
border: none;
background: papayawhip;
/* ...more styles here... */
&:hover {
box-shadow: inset 1px 1px 2px rgba(0,0,0,0.1);
}
@media (min-width: 650px) {
font-size: 1.5em;
}
`;
這個 Input 組件現在將擁有很好的鼠標懸停樣式,并將在大屏幕上稍稍變大一些。讓我們看看這些輸入框有或者沒有占位符時的樣子:
以上組件在瀏覽器中的顯示效果
如你所見,創建一個具有樣式的容器組件或者創建一個具有邏輯的展示性組件是不可能的。我們也創建的是許多小型組件并將他們組合到大型容器中,而且由于沒有可見的類,我們不可能多次使用他們。
從根本上來講,通過使用 styled-components ,我們必須去構建一個良好的組件系統——沒別的可能。他強制我們使用最佳實踐——不需要特別的代碼架構審查。
Styled-components 提供很多很好的特性,比如內置主題與完全的 React Native 支持。我建議你看一看文檔并在你的項目中試一試。不用擔心最佳實踐,這使得開發體驗大大提升和加快。我當然是很偏心的,但我再也不想回去使用其他的樣式方法構建 React 應用了。
參考
智能推薦
Redux04 React + Redux 最佳實踐
本文由 簡悅 SimpRead 轉碼, 原文地址 https://github.com/sorrycc/blog/issues/1 更新:我們基于此最佳實踐做了一個封裝方案:dva,可以簡化使用 redux 和 redux-saga 時很多繁雜的操作。 前端變化雖快,但其實一直都圍繞這幾個概念在轉: URL - 訪問什么頁面 Data - 顯示什么信息 View - 頁面長成什么樣 Action ...
源碼分析:react hook 最佳實踐(上篇)
文章目錄 源碼分析:react hook 最佳實踐(上篇) 前言 2條規則 為什么? 源碼分析 useState 使用方式 為什么? 源碼分析 useEffect 使用方式 為什么? 源碼分析 useMemo 使用方式 為什么? 源碼分析 useCallback 使用方式 為什么? 源碼分析 下篇介紹 參考 源碼分析:react hook 最佳實踐(上篇) 原文鏈接 前言 本文從 mini Rea...
freemarker + ItextRender 根據模板生成PDF文件
1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...
電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!
Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...
猜你喜歡
requests實現全自動PPT模板
http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...
Linux C系統編程-線程互斥鎖(四)
互斥鎖 互斥鎖也是屬于線程之間處理同步互斥方式,有上鎖/解鎖兩種狀態。 互斥鎖函數接口 1)初始化互斥鎖 pthread_mutex_init() man 3 pthread_mutex_init (找不到的情況下首先 sudo apt-get install glibc-doc sudo apt-get install manpages-posix-dev) 動態初始化 int pthread_...
統計學習方法 - 樸素貝葉斯
引入問題:一機器在良好狀態生產合格產品幾率是 90%,在故障狀態生產合格產品幾率是 30%,機器良好的概率是 75%。若一日第一件產品是合格品,那么此日機器良好的概率是多少。 貝葉斯模型 生成模型與判別模型 判別模型,即要判斷這個東西到底是哪一類,也就是要求y,那就用給定的x去預測。 生成模型,是要生成一個模型,那就是誰根據什么生成了模型,誰就是類別y,根據的內容就是x 以上述例子,判斷一個生產出...
styled-components —— React 中的 CSS 最佳實踐
https://zhuanlan.zhihu.com/p/29344146 Styled-components 是目前 React 樣式方案中最受關注的一種,它既具備了 css-in-js 的模塊化與參數化優點,又完全使用CSS的書寫習慣,不會引起額外的學習成本。本文是 styled-components 作者之一 Max Stoiber 所寫,首先總結了前端組件化樣式中的最佳實踐原則,然后在此基...