react|react 也就这么回事 05 —— 组件 & Props
什么是组件:用来实现局部功能的可复用代码片段
比如很多界面会用到“分页”功能,因此可以将它封装成独立的组件
文章图片
这样用到分页的界面只需引入该组件而不必重新写代码
1 定义组件
在 React 中有两种组件,一种是函数组件,一种是类组件
1.1 函数组件
定义组件最简单的方式就是编写 JavaScript 函数
对 React 来说,能够返回一个 React 元素的 函数 就叫组件
function MyComponent() {
return 我是一个函数组件;
}
在线代码
1.2 class 组件
类组件的声明过程会比较繁琐一些,需要使用 class、extends 关键字,来继承
React.Component{}
render()
函数会返回该类的实例要创建的元素。class MyComponent extends React.Component {
render() {
return 我是一个class组件;
}
}
在线代码
无论是函数组件还是class组件,在 React 中是等效的,不过 class 组件有更多的特性
2 渲染组件 同一个组件在不同界面使用,可能会想要展示不同的内容
比如我们自定义的组件包含了一个
h2
标签,如果我们想要在两个不同的界面分别展示函数
和class
怎么办?可以在使用组件时添加属性,react 会将添加的属性转换为一个对象传递给组件,这个对象称为"props"
函数组件和class组件可以分别通过“形参”和实例属性来使用这个对象
比如:
function MyComponent(props) {
console.log(props)
return 我是一个函数组件;
}
ReactDOM.render(
,
document.getElementById("root")
);
class MyComponent extends React.Component {
render() {
console.log(this.props);
return 我是一个class组件;
}
}
ReactDOM.render(
,
document.getElementById("root")
);
两者输出同样的对象:
文章图片
在线代码
于是我们可以传入不同的属性,来让组件呈现不同的内容:
function MyComponent(props) {
return 我是一个{props.name}组件;
}ReactDOM.render(
,
document.getElementById("root")
);
在线代码
这个例子中发生了这些事:
- 我们调用
ReactDOM.render()
函数,并传入
作为参数。 - React 调用
MyComponent
组件,并将{name: '自定义函数'}
作为 props 传入。 MyComponent
组件将我是一个自定义函数组件
元素作为返回值。- React DOM 将 DOM 高效地更新为
我是一个自定义函数组件
。
- 组件名称必须以大写字母开头。
- 传入属性值为字符串和数字的区别:
数字:
字符串:
- 多个属性可以使用扩展运算符
const obj = { name: 'React', age: 18 }
注意{}
不能省略
3 组合组件 组件可以在其输出中引用其他组件
例如,我们可以创建一个可以多次渲染
Welcome
组件的 App
组件:function Welcome(props) {
return Hello, {props.name};
}function App() {
return (
);
}ReactDOM.render(
,
document.getElementById('root')
);
这就可以让我们用同一组件来构建不同层次的新组件
在线代码
4 提取组件 对于一个复杂的组件,我们应该尽量将其拆分为更小的组件,以提高其可维护性和可读性
例如,参考如下
Comment
组件:function Comment(props) {
return ({props.author.name}{props.text}{formatDate(props.date)});
}
该组件用于描述一个社交媒体网站上的评论功能,它接收
author
(对象),text
(字符串)以及 date
(日期)作为 props。该组件由于嵌套的关系,变得难以维护,且很难复用它的各个部分。因此,让我们从中提取一些组件出来。
首先,我们将提取
Avatar
组件:function Avatar(props) {
return (
);
}
Avatar
不需知道它在 Comment
组件内部是如何渲染的。因此,我们给它的 props 起了一个更通用的名字:user
,而不是 author
。建议从组件自身的角度命名 props,而不是依赖于调用组件的上下文命名。
现在可以在
Comment
中引用Avatar
组件了:function Comment(props) {
return ({props.author.name}{props.text}{formatDate(props.date)});
}
接下来,我们将提取
UserInfo
组件,该组件在用户名旁渲染 Avatar
组件:function UserInfo(props) {
return ({props.user.name});
}
进一步简化
Comment
组件:function Comment(props) {
return ( {props.text}{formatDate(props.date)});
}
5 Props 的只读性 对于 props,React 有一个严格的规则:
组件无论是使用函数声明还是通过 class 声明,都决不能修改自身的 props。6 计时器
function tick() {
const element = (
当前时间: {new Date().toLocaleTimeString()}.
);
ReactDOM.render(element, document.getElementById('root'));
}setInterval(tick, 1000);
这个例子中,每秒调用一次 tick 函数,页面会更新当前时间
在线代码
将它封装为一个组件:
class Clock extends React.Component {
render() {
return 现在时间:{new Date().toLocaleTimeString()};
}
}function tick() {
ReactDOM.render( , document.getElementById("root"));
}setInterval(tick, 1000);
我们将时间写死在了 JSX 中
在线代码
如果我们想自己传入显示的内容:
class Clock extends React.Component {
render() {
const time = this.props.time;
return 现在时间:{time};
}
}function tick() {
ReactDOM.render(
,
document.getElementById("root")
);
}setInterval(tick, 1000);
这样我们就可以控制显示的格式
【react|react 也就这么回事 05 —— 组件 & Props】在线代码
公众号【前端嘛】提问答疑
推荐阅读
- react-router|react-router v6嵌套路由简单案例
- 聊聊jenkins部署vue/react项目的问题
- react底层的四大核心内容架构详解
- React组件性能优化
- react|React Native 制作iOS静态库供其他原生项目使用
- (六)React|(六)React Ant Design Pro + .Net5 WebApi(后端环境搭建-EF Core)
- 关于react|关于react hooks的一些Q&A
- react|react hooks源码核心(ReactCurrentDispatcher)
- react|react hooks核心(hooktype和ReactCurrentDispatcher)
- react|react hooks 本质探索 - useMemo、useEffect源码解析