react 也就这么回事 05 —— 组件 & Props
什么是组件:用来实现局部功能的可复用代码片段
比如很多界面会用到“分页”功能,因此可以将它封装成独立的组件
这样用到分页的界面只需引入该组件而不必重新写代码
1 定义组件
在 React 中有两种组件,一种是函数组件,一种是类组件
1.1 函数组件
定义组件最简单的方式就是编写 JavaScript 函数
对 React 来说,能够返回一个 React 元素的 函数 就叫组件
function MyComponent() {
return <h2>我是一个函数组件</h2>;
}
1.2 class 组件
类组件的声明过程会比较繁琐一些,需要使用 class、extends 关键字,来继承React.Component{}
render()
函数会返回该类的实例要创建的元素。
class MyComponent extends React.Component {
render() {
return <h2>我是一个class组件</h2>;
}
}
无论是函数组件还是class组件,在 React 中是等效的,不过 class 组件有更多的特性
2 渲染组件
同一个组件在不同界面使用,可能会想要展示不同的内容
比如我们自定义的组件包含了一个h2
标签,如果我们想要在两个不同的界面分别展示函数
和class
怎么办?
可以在使用组件时添加属性,react 会将添加的属性转换为一个对象传递给组件,这个对象称为"props"
函数组件和class组件可以分别通过“形参”和实例属性来使用这个对象
比如:
function MyComponent(props) {
console.log(props)
return <h2>我是一个函数组件</h2>;
}
ReactDOM.render(
<MyComponent a="1" b="2" />,
document.getElementById("root")
);
class MyComponent extends React.Component {
render() {
console.log(this.props);
return <h2>我是一个class组件</h2>;
}
}
ReactDOM.render(
<MyComponent a="1" b="2" />,
document.getElementById("root")
);
两者输出同样的对象:
于是我们可以传入不同的属性,来让组件呈现不同的内容:
function MyComponent(props) {
return <h2>我是一个{props.name}组件</h2>;
}
ReactDOM.render(
<MyComponent name="自定义函数" />,
document.getElementById("root")
);
这个例子中发生了这些事:
- 我们调用
ReactDOM.render()
函数,并传入<MyComponent name="自定义函数" />
作为参数。 - React 调用
MyComponent
组件,并将{name: '自定义函数'}
作为 props 传入。 MyComponent
组件将<h2>我是一个自定义函数组件</h2>
元素作为返回值。- React DOM 将 DOM 高效地更新为
<h2>我是一个自定义函数组件</h2>
。
3 注意点
组件名称必须以大写字母开头。
传入属性值为字符串和数字的区别:
数字:
<MyComponent a={1} />
字符串:
<MyComponent a="1" />
多个属性可以使用扩展运算符
const obj = { name: 'React', age: 18 }
<MyComponent {...obj} />
注意
{}
不能省略
3 组合组件
组件可以在其输出中引用其他组件
例如,我们可以创建一个可以多次渲染 Welcome
组件的 App
组件:
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
function App() {
return (
<div>
<Welcome name="Sara" />
<Welcome name="Cahal" />
<Welcome name="Edite" />
</div>
);
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
这就可以让我们用同一组件来构建不同层次的新组件
4 提取组件
对于一个复杂的组件,我们应该尽量将其拆分为更小的组件,以提高其可维护性和可读性
例如,参考如下 Comment
组件:
function Comment(props) {
return (
<div className="Comment">
<div className="UserInfo">
<img className="Avatar"
src={props.author.avatarUrl}
alt={props.author.name}
/>
<div className="UserInfo-name">
{props.author.name}
</div>
</div>
<div className="Comment-text">
{props.text}
</div>
<div className="Comment-date">
{formatDate(props.date)}
</div>
</div>
);
}
该组件用于描述一个社交媒体网站上的评论功能,它接收 author
(对象),text
(字符串)以及 date
(日期)作为 props。
该组件由于嵌套的关系,变得难以维护,且很难复用它的各个部分。因此,让我们从中提取一些组件出来。
首先,我们将提取 Avatar
组件:
function Avatar(props) {
return (
<img className="Avatar"
src={props.user.avatarUrl}
alt={props.user.name}
/>
);
}
Avatar
不需知道它在 Comment
组件内部是如何渲染的。因此,我们给它的 props 起了一个更通用的名字:user
,而不是 author
。
建议从组件自身的角度命名 props,而不是依赖于调用组件的上下文命名。
现在可以在Comment
中引用Avatar
组件了:
function Comment(props) {
return (
<div className="Comment">
<div className="UserInfo">
<Avatar user={props.author} />
<div className="UserInfo-name">
{props.author.name}
</div>
</div>
<div className="Comment-text">
{props.text}
</div>
<div className="Comment-date">
{formatDate(props.date)}
</div>
</div>
);
}
接下来,我们将提取 UserInfo
组件,该组件在用户名旁渲染 Avatar
组件:
function UserInfo(props) {
return (
<div className="UserInfo">
<Avatar user={props.user} />
<div className="UserInfo-name">
{props.user.name}
</div>
</div>
);
}
进一步简化 Comment
组件:
function Comment(props) {
return (
<div className="Comment">
<UserInfo user={props.author} />
<div className="Comment-text">
{props.text}
</div>
<div className="Comment-date">
{formatDate(props.date)}
</div>
</div>
);
}
5 Props 的只读性
对于 props,React 有一个严格的规则:
组件无论是使用函数声明还是通过 class 声明,都决不能修改自身的 props。
6 计时器
function tick() {
const element = (
<h2>当前时间: {new Date().toLocaleTimeString()}.</h2>
);
ReactDOM.render(element, document.getElementById('root'));
}
setInterval(tick, 1000);
这个例子中,每秒调用一次 tick 函数,页面会更新当前时间
将它封装为一个组件:
class Clock extends React.Component {
render() {
return <h2>现在时间:{new Date().toLocaleTimeString()}</h2>;
}
}
function tick() {
ReactDOM.render(<Clock />, document.getElementById("root"));
}
setInterval(tick, 1000);
我们将时间写死在了 JSX 中
如果我们想自己传入显示的内容:
class Clock extends React.Component {
render() {
const time = this.props.time;
return <h2>现在时间:{time}</h2>;
}
}
function tick() {
ReactDOM.render(
<Clock time={new Date().toLocaleTimeString()} />,
document.getElementById("root")
);
}
setInterval(tick, 1000);
这样我们就可以控制显示的格式
公众号【前端嘛】
react 也就这么回事 05 —— 组件 & Props的更多相关文章
- React学习笔记 - 组件&Props
React Learn Note 4 React学习笔记(四) 标签(空格分隔): React JavaScript 三.组件&Props 组件可以将UI切分成一些独立的.可复用的部件,这样你 ...
- React文档(五)组件和props
组件可以让你将UI分割成独立的,可复用的模块,然后考虑将每个模块彼此隔离.从概念上理解,组件就像js中的函数.他们接受随意的输入(被称为props)然后返回React元素来描述屏幕上应该出现什么. 函 ...
- React 组件&Props
组件&Props 组件&Props 组件可以将UI切分成一些独立的.可复用的部件,这样你就只需要专注于构建每一个单独的组件. 组件从概念上看就像是函数,它可以接受任意的输入值(称之为& ...
- React学习(一)父子组件通讯
React父子组件之间通讯,利用props和state完成,首先React是单向数据流,父组件可以向子组件传递props: 实现父子组件双向数据流整体的思路是: 1,父组件可以向子组件传递props, ...
- 【每天半小时学框架】——React.js的模板语法与组件概念
[重点提前说:组件化与虚拟DOM是React.js的核心理念!] 先抛出一个论题:在React.js中,JSX语法提倡将 HTML 和 CSS 全都写入到JavaScrip ...
- react 入坑笔记(三) - Props
React Props props - 参数. 组件类 React.Component 有个 defaultProps 属性,以 class xxx extend React.Component 形式 ...
- react学习笔记1之声明组件的两种方式
//定义组件有两种方式,函数和类 function Welcome(props) { return <h1>Hello, {props.name}</h1>; } class ...
- React对比Vue(04 父子组件的通信 )
跟vue差不多 都是props,但是react里面不仅可以给子组件传值,还可以传方法,MD尽然还可以把自己传给子组件,(卧槽vue可没有这个啊 ) vue的传递值差不多,传方法就不用了,子组件可以掉 ...
- React中的Context——从父组件传递数据
简介:在React中,数据可以以流的形式自上而下的传递,每当你使用一个组件的时候,你可以看到组件的props属性会自上而下的传递.但是,在某些情况下,我们不想通过父组件的props属性一级一级的往下传 ...
随机推荐
- IDEA中的.iml文件和.idea文件夹作用和意义
感谢原文作者:LZHHuo 原文链接:https://blog.csdn.net/weixin_41699562/article/details/99552780 .iml文件 idea 对modul ...
- Swift 介绍
简介 Swift 语言由苹果公司在 2014 年推出,用来撰写 OS X 和 iOS 应用程序 2014 年,在 Apple WWDC 发布 几家欢喜,几家愁 愁者:只学Object-C的人 欢喜者: ...
- 学习jsp篇:jsp简单实例之一注册
编程环境:IDEA,Tomcat ,JavaEE 实例一.注册 1.先在IDEA建一个web工程(不懂的可以在网上搜,一大堆..)ServletTest,在工程目录下的web目录建一个文件夹regis ...
- Jmeter平均响应时间和TPS的计算方法
转自:https://www.cnblogs.com/xianlai-huang/p/7795215.html Jmeter的Throughput和平均RT的计算 1.TPS:每秒处理的事务数,jme ...
- pytest(4)-测试用例执行顺序
前言 上一篇文章我们讲了在pytest中测试用例的命名规则,那么在pytest中又是以怎样的顺序执行测试用例的呢? 在unittest框架中,默认按照ACSII码的顺序加载测试用例并执行,顺序为:09 ...
- Keycloak 团队宣布他们正在弃用大多数 Keycloak 适配器,包括Spring Security和Spring Boot
2月14日,Keycloak 团队宣布他们正在弃用大多数 Keycloak 适配器. 其中包括Spring Security和Spring Boot的适配器,这意味着今后Keycloak团队将不再提供 ...
- linux可以这样玩 之 杂乱无章的随笔(不定期更新)
文章目录 快速重命名 vim的进化 vim高亮当前行 vim列编辑 vim块编辑 vim行编辑 vim 中替换内容 vim保留当前已经编辑的内容,切换到其他用户继续编辑 修改服务的进程限制 CentO ...
- Python基础—编码(Day2)
一.字符编码 1.ASCII码:包含英文.数字.特殊字符,8位=1字节byte =1个字符,如: 0010 1010 ASCII码表里的字符总共有256个,前128个为常用的字符如运算符,后128个称 ...
- 《操作系统导论》第5章 | 进程API
本章主要讨论UNIX系统中的进程创建.UNIX系统采用了一种非常有趣的创建新进程的方式,即通过一对系统调用:fork()和exec().进程还可以通过第三个系统调用wait(),来等待其创建的子进程执 ...
- LibOpenCM3(二) 项目模板 Makefile分析
目录 LibOpenCM3(一) Linux下命令行开发环境配置 LibOpenCM3(二) 项目模板 Makefile分析 LibOpenCM3 项目模板 项目模板地址: https://githu ...