在过去的29天内,除了直接绑在JSX元素上外,我们从来都没有提过要如何在React处理CSS code。其实只要设定好打包工具,我们就能直接在任何元件档使用import引入css档。例如如果你是使用create-react-app建立专案的朋友,就能这样写:
import ".css档路径";
然而这样做有个问题。
一般在做SPA的时候,通常是把所有css档打包成一个或多个档案,并在第一次载入网页时就全部引入。但这会让开发者原本想要隶属於个别元件的css程序码同时生效,导致本来应该分开的css程序码互相影响。 如果想要最简易的解决这个问题,除了把style写在JSX的props上外,就要引用第三方套件。
除非你能保证,你自己、你的同事、你未来的接班人、你过去的古人(?) 都没有使用同样的class、id 或是其他哩哩抠抠的选取器......
现在,我们就来介绍一款热门的React style处理套件 - Styled-Components
请打开terminal,输入:
npm install --save styled-components
Styled-Component可以让我们撰写css code後,产生「专属这组css」的React元件。他的语法很特别:
import styled from 'styled-components';
const 元件 = styled.你想使用的DOM元素`css程序码`
//在JSX使用时
<元件></元件>
css程序码要在.js档以字串的方式写在最後面。举例来说,本来我们的MenuItem长这样:
import React, { memo } from 'react';
const menuItemStyle = {
marginBottom: "7px",
paddingLeft: "26px",
listStyle: "none"
};
function MenuItem(props){
return <li style={menuItemStyle}>{props.text}</li>;
}
export default memo(MenuItem);
切换成Styled-Components後就会变这样:
import React, { memo } from 'react';
import styled from 'styled-components';
const MenuStyleItem = styled.li`
margin-bottom: 7px;
padding-left: 26px;
list-style: none;
`;
function MenuItem(props){
return <MenuStyleItem>{props.text}</MenuStyleItem>;
}
export default memo(MenuItem);
实际观看执行结果,你会发现显示的虽然是一般的<li>
,但它上面多了一组特别的class,而且我们撰写的css程序码自动以这个class为选取器运作:
因为相同的Styled-Components元件会产生同样且不与其他元件重复的class,所以我们就能避免在不同地方使用到相同css选取器而互相影响。
另外,一般会习惯把定义Styled-Components的地方拉出来和本来的元件分开。就跟以前会把css跟html档分开的感觉很像。只是现在你又能更方便的制造相同style的元素:
import styled from 'styled-components';
const MenuStyleItem = styled.li`
margin-bottom: 7px;
padding-left: 26px;
list-style: none;
`;
export { MenuStyleItem };
import React, { memo } from 'react';
import { MenuStyleItem } from './MenuItemStyle';
function MenuItem(props){
return <MenuStyleItem>{props.text}</MenuStyleItem>;
}
export default memo(MenuItem);
你可以在Styled-Components上直接绑定本来原生DOM元素就会运作的props,例如onClick
,该props会自动被给予DOM元素,不需要做任何而外的事情。
另外,我们也能透过ES6的字串模板,让css根据props的值而变动。像是下面我们给了MenuStyleItem一个color={"blue"}
:
import React, { memo } from 'react';
import { MenuStyleItem } from './MenuItemStyle';
function MenuItem(props){
return <MenuStyleItem color={"blue"}>{props.text}</MenuStyleItem>;
}
export default memo(MenuItem);
我们就能把props.color
设为color
的值(如果没有给props.color
则把color设定为"black"
)。
import styled from 'styled-components';
const MenuStyleItem = styled.li`
margin-bottom: 7px;
padding-left: 26px;
list-style: none;
color: ${props => props.color ? props.color : "black"};
`;
export { MenuStyleItem };
你可以透过Styled元件.defaultProps
来设定给参数预设值。藉此达到制作「主题」的效果。当使用元件的人没有给对应的style的props时,Styled元件就会以预设的参数造型显示:
import styled from 'styled-components';
const MenuStyleItem = styled.li`
margin-bottom: 7px;
padding-left: 26px;
list-style: none;
color: ${props => props.theme.color};
`;
MenuStyleItem.defaultProps = {
theme: {
color: "mediumseagreen"
}
}
export {MenuStyleItem};
import React, { memo } from 'react';
import { MenuStyleItem } from './MenuItemStyle';
function MenuItem(props){
return <MenuStyleItem>{props.text}</MenuStyleItem>;
}
export default memo(MenuItem);
另外你也可以透过搭配useContext或是Redux达到制造相同主题的效果,这里就不示范了。
最後,比较乾净的分档方式应该是为单一元件创立一个资料夹,在里面放置专属於它的元件程序和style程序。但这个就是不同人/团队的习惯问题了。
import React, { memo } from 'react';
import { MenuStyleItem } from './style';
function MenuItem(props){
return <MenuStyleItem onClick={()=>{console.log(props.handleClick)}}>{props.text}</MenuStyleItem>;
}
export default memo(MenuItem);
import styled from 'styled-components';
const MenuStyleItem = styled.li`
margin-bottom: 7px;
padding-left: 26px;
list-style: none;
color: ${props => props.theme.color};
`;
MenuStyleItem.defaultProps = {
theme: {
color: "mediumseagreen"
}
}
export {MenuStyleIStyleItem};
另外,StyleComponent中也能撰写像是伪元素的语法,更多进阶使用可以参考官方文件
在这个系列中,除了这两个hook之外
我们已经把所有其他官方提供的React hook、现今业界React专案开发一定会用到的语法、套件以及他们需要用到的对应情境都讲解了一遍。上面这两个有需要的时候再去查就好。
有关React SSR的文章我应该会後续几个月内再继续发,到时候也是会发在这个系列。
最後,我希望看这系列文的读者不是只为了工作才逼自己跟随React语法写程序,而是能够理解框架是长期演变而来的。所谓的框架,只是把过去开发者发现中大型专案几乎一定会用到的Design Pattern、架构都帮你封装好。我们应该思考的是如何让「元件化的架构」搭配框架提供的功能而变得更乾净、更好用、更能弹性的封装,而不是单纯写出一个能用的React Component。
这30天的内容如果都能理解并熟悉,我相信在2020年你绝对能够用React找到一份工作。
因为2020年只剩2个月了,读者练完这系列、投完履历,2个月应该也过了......
今年我没有先准备。而且在参赛的期间,我同时要实习、准备推甄、准备另一个比赛、准备通识报告......可以完赛我真的觉得不可思议。
在撰写技术教学文的时候,我会希望在介绍一个新单元时,应该要从「为什麽需要这个工具」开始,慢慢从「为什麽架构要这样设计」,再继续去提他的语法跟用法。虽然自己不是读者很难判断是不是这样,但希望这次我有做到这个目标。
如果这中间有哪篇不清楚、有写错的地方,或是你看完这系列之後有什麽想跟我交流的,都欢迎留言在底下跟我说。
这篇的上一篇:https://ithelp.ithome.com.tw/articles/10283...
Azure Defender提供目的导向的使用者介面,可管理和调查 Microsoft 365 服务...
Youtube连结:https://bit.ly/3m1VQWV 在我们了解Binary Tree...
Raid可以理解为是将多个硬碟组合在一起,利用虚拟储存技术,形成一个硬碟阵列,用来提升储存空间和制造...
前言 参考 Tyler Potts 的 Demo 影片- Build a Music app usi...