什么是组件:用来实现局部功能的可复用代码片段

比如很多界面会用到“分页”功能,因此可以将它封装成独立的组件

这样用到分页的界面只需引入该组件而不必重新写代码

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")
);

在线代码

这个例子中发生了这些事:

  1. 我们调用 ReactDOM.render() 函数,并传入 <MyComponent name="自定义函数" /> 作为参数。
  2. React 调用 MyComponent 组件,并将 {name: '自定义函数'} 作为 props 传入。
  3. MyComponent 组件将 <h2>我是一个自定义函数组件</h2> 元素作为返回值。
  4. 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的更多相关文章

  1. React学习笔记 - 组件&Props

    React Learn Note 4 React学习笔记(四) 标签(空格分隔): React JavaScript 三.组件&Props 组件可以将UI切分成一些独立的.可复用的部件,这样你 ...

  2. React文档(五)组件和props

    组件可以让你将UI分割成独立的,可复用的模块,然后考虑将每个模块彼此隔离.从概念上理解,组件就像js中的函数.他们接受随意的输入(被称为props)然后返回React元素来描述屏幕上应该出现什么. 函 ...

  3. React 组件&Props

    组件&Props 组件&Props 组件可以将UI切分成一些独立的.可复用的部件,这样你就只需要专注于构建每一个单独的组件. 组件从概念上看就像是函数,它可以接受任意的输入值(称之为& ...

  4. React学习(一)父子组件通讯

    React父子组件之间通讯,利用props和state完成,首先React是单向数据流,父组件可以向子组件传递props: 实现父子组件双向数据流整体的思路是: 1,父组件可以向子组件传递props, ...

  5. 【每天半小时学框架】——React.js的模板语法与组件概念

           [重点提前说:组件化与虚拟DOM是React.js的核心理念!]        先抛出一个论题:在React.js中,JSX语法提倡将 HTML 和 CSS 全都写入到JavaScrip ...

  6. react 入坑笔记(三) - Props

    React Props props - 参数. 组件类 React.Component 有个 defaultProps 属性,以 class xxx extend React.Component 形式 ...

  7. react学习笔记1之声明组件的两种方式

    //定义组件有两种方式,函数和类 function Welcome(props) { return <h1>Hello, {props.name}</h1>; } class ...

  8. React对比Vue(04 父子组件的通信 )

    跟vue差不多 都是props,但是react里面不仅可以给子组件传值,还可以传方法,MD尽然还可以把自己传给子组件,(卧槽vue可没有这个啊 )  vue的传递值差不多,传方法就不用了,子组件可以掉 ...

  9. React中的Context——从父组件传递数据

    简介:在React中,数据可以以流的形式自上而下的传递,每当你使用一个组件的时候,你可以看到组件的props属性会自上而下的传递.但是,在某些情况下,我们不想通过父组件的props属性一级一级的往下传 ...

随机推荐

  1. ApacheCN 深度学习译文集 20201218 更新

    新增了四个教程: Python 人工智能中文版 0 前言 1 人工智能简介 2 人工智能的基本用例 3 机器学习管道 4 特征选择和特征工程 5 使用监督学习的分类和回归 6 集成学习的预测分析 7 ...

  2. 社交网络分析的 R 基础:(四)循环与并行

    前三章中列出的大多数示例代码都很短,并没有涉及到复杂的操作.从本章开始将会把前面介绍的数据结构组合起来,构成真正的程序.大部分程序是由条件语句和循环语句控制,R 语言中的条件语句(if-else)和 ...

  3. 2020-11-21 f

    题意:给定一个长度为 \(n\) 的序列 \(A\),\(A_i \in [0, 2 ^ k)\).定义 \(f(x)\) 为 \(A_1\) ^ \(x\),\(A_2\) ^ \(x \cdots ...

  4. springboot实现分布式锁(spring integration,redis)

    Springboot实现分布式锁(Spring Integration+Redis) 一.在项目的pom.xml中添加相关依赖 1)Spring Integration依赖 <dependenc ...

  5. shell脚本之循环语句与函数

    shell脚本之循环语句与函数 echo的用法: echo -n #表示不换行输出 echo -e #输出转义字符,将转义后的内容输出到屏幕上 转义字符: \n :换行,被输出的字符从"\n ...

  6. serverless入门介绍

    1.什么是serverless Serverless 架构作为一种新型的云计算范式,是云原生时代一种革命性的架构,颠覆了传统意义上对软件应用部署和运营的认识.本节对 Serverless 架构的基本概 ...

  7. Git重命名远程分支

    一.重命名本地分支 将hot_fix分支重命名为bug_fix git branch -m hot_fix bug_fix 二.推送重命名后的本地分支到远程仓库 git push origin bug ...

  8. 274-基于XC7V690T的3U VPX信号处理板

    一.板卡概述 本板卡系我司自主研发的基于3U VPX导冷架构的信号处理板,适用于高速图像处理,雷达信号处理等.芯片采用工业级设计.该处理板包含1片Xilinx公司的Virtex7系列FPGA-XC7V ...

  9. jenkins发布代码选择不同分支

    jenkins上传代码分支以前都是用变量的方式,手动实现.过程就像这样 构建时候的界面就像下面这样,需要手动输入分支版本. 或者有固定的上线分支,用参数化构建 选项参数 来选择.总之这些方法比较传统, ...

  10. TCP三次握手原理

    本文主要讲述的是 1.TCP协议三次握手原理,以及为什么要三次握手,两次握手带来的不利后果. 2.TCP协议四次挥手原理,为什么要四次挥手. TCP协议三次握手原理: 首先,给张图片,建立TCP三次握 ...