🚀 优质资源分享 🚀
学习路线指引(点击解锁) | 知识定位 | 人群定位 |
---|---|---|
🧡 Python实战微信订餐小程序 🧡 | 进阶级 | 本课程是python flask+微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一个全栈订餐系统。 |
💛Python量化交易实战💛 | 入门级 | 手把手带你打造一个易扩展、更安全、效率更高的量化交易系统 |
其他章节请看:
react 的第一个组件
写了 react 有一个半月,现在又有半个月没写了,感觉对其仍旧比较陌生。
本文分两部分,首先聊一下 react 的相关概念
,然后不使用任何语法糖(包括 jsx)或可能隐藏底层技术的便利措施来构建 React 组件
。
Tip:从一项新技术的底层元素起步有利于使用者更好的长期使用它
跨平台
大部分 react 应用是在 Web 平台
上。而 React Native
和 React VR
这样的项目则创造了 react 应用在其他平台上运行的可能
React 应用主要成分
组件
组件是 React 中最基本单元
。
组件通常对应用户界面的一部分,比如导航。也可以担任数据格式化等职责。
可以将任何东西作为组件,尽管并不是所有东西作为组件都有意义。
如果将整个界面作为组件,并且没有子组件或进一步的细分,那么对自己并没有什么帮助。倘若,将界面不同部分拆解成可以组合,复用的部分,却很有帮助。
组件具有良好的封装性
、复用性
和组合性
。有助于为使用者提供一个更简单的方式来思考和构建用户界面。使用 React 构建应用就像使用积木来搭建项目,而构建应用时有取之不尽的“积木”
将 UI 分解成组件可以让人更轻松的处理应用不同的部分。
组件需要一起工作,也就是说组件可以组合起来形成新的组件。组件组合
也是 React 最强大的部分之一。
如果身处一个中大型团队,可以将组件发布到私有注册中心(npm 或者其他)
React 组件还有一个方面就是生命周期方法
。当组件经过其生命周期的不同时期时(挂在、更新、卸载等),可以使用可预测、定义良好的方法。
React 库
React 核心库与 react-dom 和 react-native 紧密配合,侧重组件的规范和定义
。能让开发者构建一个组件树,该组件树能够被浏览器和其他平台所使用。
react-dom 就是一个渲染器
。针对浏览器环境和服务端渲染。
比如我们要将组件渲染到浏览器,就得用到 react-dom。
React Native
库专注于原生平台,能够为 ios、android 和其他平台创建 react 应用。
第三方库
React 不自带 http
等其他前端常用工具库。开发者可以自由的选择对于工作最好的工具。
react 的权衡
react 属于 专一型
,主要关注 UI 试图方面。
而 angular 属于 通用型
,其内置了许多解决方案,例如 http 调用、路由、国际化、字符串和数字格式化…
Tip:通常一些优秀的团队会用这两种方式。
React 的创建主要用于 Facebook 的 UI 需求。虽然大多数的 web 应用在此范围之内,但也有一些应用不在。
React 是一种抽象,也存在抽象的代价
。React 以特定的方式构建并通过 api 向外暴露,开发者会失去对底层的可见性
。当然 React 也提供了紧急出口
,让开发者深入较低的抽象层级,仍然可以使用 jQuery,不过需要以一种兼容 React 的方式使用。
有时还需要为 React 的行事方式买单。或许会影响应用的小部分(即不太适合用 React 的方式来工作)
使用 React 时所做的权衡有助于使用者成为更好的开发者。
虚拟 Dom
React 旨在将复杂的任务简单化,把不必要的复杂性从开发者身上剥离出来。
鼓励开发者使用声明式
的编程而非命令式,也就是开发者声明组件在不同状态下的行为和外观即可,React 负责渲染以及更新 UI,并将性能做到恰到好处。从而让研发人员腾出时间思考其他方面。
驱动这些的主要技术之一就是虚拟dom
。
Tip:有关虚拟dom 的介绍可以参考 vue 快速入门-虚拟dom
虚拟 Dom 不是我们关注的重点。这正是 React 简单
的地方:开发者被解放出来,去关注最关注的部分。
React 的简单、非固化
什么使 React 成为大型团队的宠儿?首先是简单
,其次是非固化
。
简单的技术让人更容易理解和使用。
React 是一个非常轻量的库,只关注应用的视图。更加容易与使用者当前的技术集成,并在其他方面为使用者留下了选择的空间。一些功能固化的框架和库要求使用者要么全盘接受要么彻底不用。
简单和非固化的特性,以及恰到好处的性能,让它非常适合大大小小的项目。
组件间的关系
组件可以独立存在,也可用来创建其他组件。人们认为组件可以创建很多不同类的关系,从某种意义这是对的。
但组件更多的是以灵活的方式被使用,应该关注其独立性
和常常不带任何负担
,可组合使用。所以组件只关注其父母和孩子
,兄弟关系可以不管。
建立组件关系的过程对每个团队或项目都不尽相同,组件关系也可能会随时间而改变,我们可以不期望一次就建立完美,也无需太过担心,因为 React 会让我们的 UI 迭代没那么困难。
搭建组件的框架
首先我们将组件的框架写好:
<div id="root">
div>
<script src="https://unpkg.com/react@17/umd/react.development.js">script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js">script>
<script src="https://unpkg.com/prop-types@15.6/prop-types.js">script>
<script>
const reactElem = React.createElement(
'h1',
{title: 'i am h1'},
'Hello, world!'
)
ReactDOM.render(
reactElem,
document.getElementById('root')
);
script>
Tip:这是一个普通的 html 页面,直接通过 vscode 的 Live Server 插件运行即可
运行后的网页显示 Hello, world!
。生成的元素结构如下:
"root">
<h1 title="i am h1">Hello, world!h1>
下面我们稍微分析一下这个页面:
首先定义了一个 div 元素,接着引入三个包,作用如下:
react.js
,React 的核心库,用于定义组件的规范react-dom.js
,渲染器,用于浏览器和服务端渲染,用于创建组件和管理组件prop-types.js
,传递给组件的数据做类型检查
接着通过 React.createElement
创建一个 react 元素。
React.createElement(
type,
[props],
[...children]
)
Tip:react 元素是什么?
- react 元素是创建起来开销极小的
普通对象
- react 元素是构成 React 应用的最小砖块。react 元素之于React如同DOM元素之于DOM,react 元素组成了虚拟 DOM
- react 组件是由 react 元素构成的
最后使用 ReactDOM.render
将 React 元素渲染到 div#root
中。
// 在提供的 container 里渲染一个 React 元素,并返回对该组件的引用
ReactDOM.render(element, container[, callback])
Tip:调用 react-dom 的 render() 方法来让 React 将组建渲染出来,并对组件进行管理。
React 元素
React 元素
是你想让 React 渲染的东西的轻量表示。它可以表示为一个 Dom 元素,上文我们已经用其创建了一个 h1
的 dom 元素。
有必要再来分析一下 createElement()
的参数:
// 创建并返回指定类型的新 React 元素。其中的类型参数既可以是标签名字符串(如 'div' 或 'span'),也可以是 React 组件 类型 (class 组件或函数组件),或是 React fragment 类型。
React.createElement(
type,
[props],
[...children]
)
const reactElem = React.createElement(
'h1',
{title: 'i am h1'},
'Hello, world!'
)
type
,一个 html 标签(“div”、“h1”)或 React 类props
,指定 html 元素上要定义哪些属性或组件类的实例上可以使用哪些属性children
,还记得 React 组件是可以组合的吗?
一句话:React.createElement()
在问:
我在创建什么?
,是 Dom 元素,是 React 组件,还是React fragment。我怎么配置它?
它包含什么?
假如我们需要在页面显示如下元素:
<h2>i am h2h2>
<a href="www.baidu.com">go baidua>
<p>
<em>i am em elementem>
p>
可以这么写:
const c = React.createElement
const reactElem2 = React.createElement(
'div',
{},
c('h2', {}, 'i am h2'),
c('a', {href: 'www.baidu.com'}, 'go baidu'),
c('p', {},
c('em', {}, 'i am em element')
)
)
虚拟 DOM 树
React 是怎么把那么多 React.createElement
转换成屏幕上看到的东西的?这里得用到虚拟 dom。
虚拟 dom 和真实 dom 有着相似的结构。
为了从 React 元素中形成自己的虚拟 DOM 树
,React 会对 React.createElement 的全部 children 属性进行求值,并将结果传递给父元素。就像一个小孩反复再问 X是什么?
,直到理解 X 的每个细节,直到他能形成一棵完整的树。
React 组件
看看这段代码,我们创建了一个 React 元素并将其放入 dom 中:
<span class="hljs-keyword">const</span> c = <span class="hljs-title class\_">React</span>.<span class="hljs-property">createElement</span>
<span class="hljs-keyword">const</span> reactElem = <span class="hljs-title class\_">React</span>.<span class="hljs-title function\_">createElement</span>(
<span class="hljs-string">'div'</span>,
{},
<span class="hljs-title function\_">c</span>(<span class="hljs-string">'h2'</span>, {}, <span class="hljs-string">'i am h2'</span>),
<span class="hljs-title function\_">c</span>(<span class="hljs-string">'a'</span>, {<span class="hljs-attr">href</span>: <span class="hljs-string">'www.baidu.com'</span>}, <span class="hljs-string">'go baidu'</span>),
<span class="hljs-title function\_">c</span>(<span class="hljs-string">'p'</span>, {},
<span class="hljs-title function\_">c</span>(<span class="hljs-string">'em'</span>, {}, <span class="hljs-string">'a am em element'</span>)
)
)
<span class="hljs-title class\_">ReactDOM</span>.<span class="hljs-title function\_">render</span>(
reactElem,
<span class="hljs-variable language\_">document</span>.<span class="hljs-title function\_">getElementById</span>(<span class="hljs-string">'root'</span>)
);
如果我们需要扩展 reactElem 的功能、样式以及其他UI相关?这时可以使用组件
。
组件可以将这些有效的组织在一起。
所以,要真正构建东西,不仅仅需要 React 元素,还需要组件。
React 组件就像是 React 元素,但 React 组件拥有更多特性。React 组件是帮助将 React 元素和函数组织到一起的类
我们可以使用函数或 js 类
创建组件。
使用 es6 的 class 来定义组件。就像这样:
class MyComponent extends React.Component {
// 必须定义 render()。否则会报错:
// MyComponent(...): No `render` method found on the returned component instance: you may have forgotten to define `render`.
render() {
// 返回单个 React 元素或 React 元素的数组
return reactElem
}
}
通常需要至少定义一个 render() 方法,几乎任何向屏幕显示内容的组件都带有 render 方法
Tip:那些不直接显示任何东西而是修改或增强其他组件的组件(称高阶组件),后续再讨论。
我们将上面示例改成组件形式:
<span class="hljs-keyword">class</span> <span class="hljs-title class\_">MyComponent</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class\_ inherited\_\_">React.Component</span>{
<span class="hljs-title function\_">render</span>(<span class="hljs-params"></span>){
<span class="hljs-keyword">const</span> c = <span class="hljs-title class\