网站首页 > 基础教程 正文
什么是组件:用来实现局部功能的可复用代码片段
比如很多界面会用到“分页”功能,因此可以将它封装成独立的组件
这样用到分页的界面只需引入该组件而不必重新写代码
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);
这样我们就可以控制显示的格式
在线代码
The End
猜你喜欢
- 2024-11-21 广州蓝景分享—16个非常有用的React组件库,前端开发必备
- 2024-11-21 03 React组件(Component)
- 2024-11-21 如何设计更优雅的 React 组件?
- 2024-11-21 2022年前端React的100道面试题的第7题:组件的constructor
- 2024-11-21 前端开发react框架 - 组件
- 2024-11-21 React-组件的两种创建方式
- 2024-11-21 放弃 React 改用 Web 组件,微软这次重构让开发者不解:没有任何意义
- 2024-11-21 React系列十 - 高阶组件以及组件补充
- 2024-11-21 具有排序、筛选、分组、虚拟化、编辑功能的React表格组件
- 2024-11-21 面试官:说说对React中类组件和函数组件的理解?有什么区别?
- 最近发表
-
- Vue3+Bootstrap5项目初始化 vue 项目初始化
- 前端程序员不得不爱的bootstrap 前端 bom
- 保姆级软路由刷机+软路由OpenWRT入门设置,新手轻松搭建软路由
- 好东西!iOS 16.5 半越狱分屏功能,教你正确安装
- Python数据可视化Dash开源库Bootstrap之折叠列表Accordion
- 终于发布!iOS 16.5 越狱工具已发布,分屏插件有效
- 超爽!iOS 16.6.1 Bootstrap 半越狱更新,有通知
- 好玩!iOS 16.6.1 半越狱玩法,这插件真生效
- 来啦!iOS 16.6.1 nathanlr 半越狱,被迫公测体验
- iOS 17.0 Bootstrap 1.2.9 半越狱来啦!更新两点
- 标签列表
-
- gitpush (61)
- pythonif (68)
- location.href (57)
- tail-f (57)
- pythonifelse (59)
- deletesql (62)
- c++模板 (62)
- css3动画 (57)
- c#event (59)
- linuxgzip (68)
- 字符串连接 (73)
- nginx配置文件详解 (61)
- html标签 (69)
- c++初始化列表 (64)
- exec命令 (59)
- canvasfilltext (58)
- mysqlinnodbmyisam区别 (63)
- arraylistadd (66)
- node教程 (59)
- console.table (62)
- c++time_t (58)
- phpcookie (58)
- mysqldatesub函数 (63)
- window10java环境变量设置 (66)
- c++虚函数和纯虚函数的区别 (66)