React Props 教程 - 制作一个按钮
2020年3月 · 预计阅读时间: 3 分钟
你在写 HTML 页面的时候肯定知道,html 标签的属性都是固定的,比如 a
标签的 href
, input
里边的 type
属性。这些属性都是内置的,不方便扩展和复用。而用 React 创建组件的话,可以给它定义一些更符合语义和逻辑的属性,比如颜色、尺寸等。这些属性在 React 里边叫做 props,你可以自己定义这些属性将会影响到组件的哪些部分。这样的一个组件,通过给它一个合适的名字,比如 Button,那么所有按钮的展现都可以用它来实现,只需要改变它的属性就可以展示为不同的样式。那今天我就教你定义一个这样的按钮组件,它有默认的背景色、文字颜色、还有实心和线框样式,后边通过属性,props,来控制它是蓝色、红色还是黑色,然后利用另一个属性来控制它是实心的背景还是线框的。好,那咱们开始吧。
#
你将学到的上一张效果图:
#
创建 React 工程使用 create-react-app 创建一个工程:
等同于
添加
classnames
依赖(稍后解释它的作用)
#
创建 Button 组件在
src
下边新建一个Button
文件夹。组件应该有自己独立的文件夹,所有跟这个组件有关的文件,比如 css、hooks 等都放到一起,这样在查看一个组件源码时,相应的文件都会在一块,方便查找。另外也方便和其他人共享这个组件,它是一个独立的整体。在
Button
文件夹创建index.js
文件,里边放用来定义按钮组件的代码。在
Button
文件夹下创建style.modules.css
文件,在这里咱们先用普通的 css 来定义按钮的样式,后续的教程里我再给你介绍styled-components
。它是一个 css-in-js 的解决方案CSS modules 的作用
这个带 modules 的 css 文件使用了
css modules
库,它是 create-react-app 工具里自带的,用来避免全局 class 名字冲突,在普通 css 下,如果不同的样式文件都同时使用了.button
这样的 class 名,那么后面的就会把前面的覆盖。使用了css modules
之后,它会自动生成随机的 class 名字。这样这个组件里边定义的 class 就不会被其他组件定义的同名的 class 给覆盖。当然你也可以不用它,有些全局的 css 可以直接定义在普通的 css 文件里。编写
button
组件的代码:react 中的组件默认都会被传递一个
props
属性,里边会默认包含一个 children 属性,也就是说在使用<Button />
组件时,两个标签中间所有的代码都会当作 children 传递进来。上边的代码,也可以使用 rest 操作符简化:比如:
删除 App 的 return 中的所有的代码,导入 Button 组件,然后把它写在 return 里边:
#
编写 Button 默认样式打开 Button 组件下的
style.modules.css
文件,写上下边的 css 代码:这里把按钮设置了背景、圆角边框、字体、指针样式和阴影。
打开 Button 组件的 index.js 文件,导入 css 文件并赋值给一个变量,这里叫
styles
:给 Button 组件加上 className 属性,这里可以用
styles.button
来访问 css 文件中的.button
的样式:可以在页面上看到,这个默认按钮的样式已经加载好了。
#
用 Props 给 Button 不同的样式在给 Button 写完默认样式之后,咱们再来定义它几个变体,比如红色、黑色。你可以在 Button 里多添加一个 color 属性,代表其他组件使用它时,可以传递一个 color 属性,Button 会根据它的值显示不同的颜色,这里我假设它有三种,一种是默认的蓝,就是不传 color 的时候的颜色,一种是红色,color 的值为 red 的时候显示,一种是黑色,在 color 为 black 的时候显示。首先咱们先把这两种颜色的 css 样式定义好:
#
classnames 组合样式在定义完这两个额外的样式之后,需要把它和.button
定义的样式组合起来。这里可以手动去拼,也可以用之前刚开始安装的 classnames 依赖库。它可以根据条件来组合 className,只有满足一定条件的 class 才会被组合进来,在咱们这里,可以这样使用:
它接收多个参数,第一个直接传递了 styles.button 这个 class,说明它无论其它属性怎么变化,它都是要有的,最后传递了一个对象,对象的 key 是 styles 中的 class 的名字,value 是 boolean 类型的,需要一个条件,返回 true 就把这个 class 加到组合中,false 就不加。那这里,如果 color 的值是 red,那么 button 中就会有 .red
定义的样式。
再在 App.js 中添加两个按钮 ,一个 color 设置为 red,一个 color 设置为 black:
需要注意的是,react 要求在返回的 JSX 中只能有一个顶级的标签,不能有并列的多个,比如不能同时写三个 button,需要把它们包装在一个大的标签下,这里我用了一个 main,作为内容容器,里边有一个 div 是 button 的容器。
#
线框样式如果再加一组线框样式的按钮呢?很简单,我再加一个type
属性,默认是primary
的,主要按钮,线框按钮的 type 叫它secondary
次要按钮,然后 classnames 添加一个新的 class,在 type 为 secondary
的时候追加到组合中:
接下来定义 secondary
样式:
在这里我把默认蓝色、红色、黑色按钮的边框和文字都设置了不同的颜色。
#
显示所有按钮样式在 App.js 中咱们显示所有不同属性的按钮,然后给按钮容器加上一个 className,用来对按钮进行排版,这里我直接用了普通的 css 样式,也就是创建工程时给生成好的 App.css,直接把它导入进来:
App.js
App.css
好了,这个使用 React Props 来展示不同样式的按钮到这里就结束了,里边几个概念:
- React 组件默认会传递 Props 参数
- 使用 props 可以传递任何自定义的属性
- 组件相关的文件都放到一个文件夹里
css modules
- 用来生成随机局部 class 名字classnames
- 用来组合多个 class
你学会了吗?如果有问题,欢迎通过下方链接参与讨论。