<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>React 开发入门 on ClearSec Wiki</title><link>https://www.clearsec.org/wikis/skills/frontend/react/</link><description>Recent content in React 开发入门 on ClearSec Wiki</description><generator>Hugo</generator><language>zh-cn</language><atom:link href="https://www.clearsec.org/wikis/skills/frontend/react/index.xml" rel="self" type="application/rss+xml"/><item><title>环境配置</title><link>https://www.clearsec.org/wikis/skills/frontend/react/prepare/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.clearsec.org/wikis/skills/frontend/react/prepare/</guid><description>&lt;h1 id="环境配置"&gt;环境配置&lt;/h1&gt;
&lt;h2 id="前置环境配置"&gt;前置环境配置&lt;/h2&gt;
&lt;p&gt;在继续下面的环境配置之前，本文档默认了你已经安装了高于 v12 的 &lt;code&gt;node&lt;/code&gt;，并且可以使用 &lt;code&gt;npm install&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;如果安装 Node.js 或者 npm 遇到困难，可以参考 &lt;a href="https://www.clearsec.org/wikis/skills/languages/node.js"&gt;Node.js 的引导文档&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id="使用-yarn-代替-npm"&gt;使用 &lt;code&gt;yarn&lt;/code&gt; 代替 &lt;code&gt;npm&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;这是一个&lt;strong&gt;可选项&lt;/strong&gt;，在实际工程之中两者并没有本质上的差别。与常用的 &lt;code&gt;npm&lt;/code&gt; 相比，&lt;code&gt;yarn&lt;/code&gt; 大多情况下具有更快的下载速度和更为清晰的命令行输出。所以我们更加推荐使用 &lt;code&gt;yarn&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;这里不具体叙述安装过程，可以参考 &lt;a href="https://yarn.bootcss.com"&gt;官网&lt;/a&gt; 上给出的方式进行安装，也可以使用 &lt;code&gt;npm install yarn -g&lt;/code&gt; 命令安装（后者可能不适用于 Linux 用户）。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;yarn&lt;/code&gt; 的命令和 &lt;code&gt;npm&lt;/code&gt; 的命令大致具有以下对应关系，更细节的关系则可以参考 &lt;a href="https://www.clearsec.org/wikis/skills/languages/node.js/npm/"&gt;npm 的引导文档&lt;/a&gt;：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;/th&gt;
					&lt;th&gt;&lt;code&gt;npm&lt;/code&gt;&lt;/th&gt;
					&lt;th&gt;&lt;code&gt;yarn&lt;/code&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;安装指定第三方库&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;npm install react --save&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;yarn add react&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;移除指定第三方库&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;npm uninstall react --save&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;yarn remove react&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;开发模式下安装&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;npm install react --save-dev&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;yarn add react --dev&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="安装-typescript"&gt;安装 TypeScript&lt;/h2&gt;
&lt;p&gt;TypeScript 是 JavaScript 的超集。简而言之，TypeScript 就是带有类型系统的 JavaScript。TypeScript 代码可以直接被编译为 JavaScript 代码并执行。&lt;/p&gt;</description></item><item><title>组件、属性与状态</title><link>https://www.clearsec.org/wikis/skills/frontend/react/basic/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.clearsec.org/wikis/skills/frontend/react/basic/</guid><description>&lt;h1 id="组件属性与状态"&gt;组件、属性与状态&lt;/h1&gt;
&lt;h2 id="组件--render-函数"&gt;组件 &amp;amp; &lt;code&gt;render&lt;/code&gt; 函数&lt;/h2&gt;
&lt;p&gt;React 的一个核心概念就是&lt;strong&gt;组件&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;组件更像是将 UI 拆分得到的独立可复用的小块，其能够接受属性的传入，并且返回出描述屏幕上的展示内容的 React 元素。&lt;/p&gt;
&lt;p&gt;我们将会从类组件入手介绍 React 组件的编写方式。一个经典的类组件的结构如下（即下发框架之中的 &lt;code&gt;App.tsx&lt;/code&gt; 文件内容）：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="kr"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ReactElement&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;Hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;每一个类组件都是 &lt;code&gt;React.Component&lt;/code&gt; 类的子类，其中我们需要重载 &lt;code&gt;render&lt;/code&gt; 函数以定义这个组件在屏幕上的展示方式（用户界面）。&lt;code&gt;render&lt;/code&gt; 函数的返回值为使用标签语法编写的 &lt;code&gt;ReactElement&lt;/code&gt;。比如说上述 &lt;code&gt;App&lt;/code&gt; 组件就返回了一句问候语，这就代表 &lt;code&gt;App&lt;/code&gt; 组件在实例化的时候会渲染出这一句问候语。&lt;/p&gt;
&lt;div class="td-alert td-alert--md alert alert-note" role="alert"&gt;&lt;div class="td-alert-heading alert-heading" role="heading"&gt;说明&lt;/div&gt;
 &lt;div class="td-alert-body"&gt;
 &lt;p&gt;&lt;strong&gt;语法拓展&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;React 对 JS/TS 语言作了一定的语法拓展，拓展后的 JS/TS 称为 JSX/TSX，最大差别就是引入了标签语法：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hello&lt;/span&gt; &lt;span class="nx"&gt;world&lt;/span&gt;&lt;span class="o"&gt;!&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;/p&amp;gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这类类似于 HTML 标签的语法定义了一个对象，其等价于以下表达：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;p&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;Hello world!&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;标签对象中允许嵌入 JS/TS 表达式，其会运算出其值后转为字符串嵌入：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Adam&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;!&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;/p&amp;gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;转化为字符串的目的是防止 XSS 攻击。
JSX/TSX 的标签语法和 HTML 类似，允许定义各种属性，这些特性以后会讲到。本文档基于 TSX 语言。&lt;/p&gt;
 &lt;/div&gt;
&lt;/div&gt;
&lt;div class="td-alert td-alert--md alert alert-warning" role="alert"&gt;&lt;div class="td-alert-heading alert-heading" role="heading"&gt;警告&lt;/div&gt;
 &lt;div class="td-alert-body"&gt;
 &lt;p&gt;&lt;strong&gt;TSX 的限制&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>生命周期</title><link>https://www.clearsec.org/wikis/skills/frontend/react/lifecycle/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.clearsec.org/wikis/skills/frontend/react/lifecycle/</guid><description>&lt;h1 id="生命周期方法"&gt;生命周期方法&lt;/h1&gt;
&lt;h2 id="react-组件的生命周期"&gt;React 组件的生命周期&lt;/h2&gt;
&lt;p&gt;我们在实际的开发之中，前端需要显示的数据、显示数据的方式往往需要根据从后端、公开平台等处拉取的信息确定，那么我们就需要考虑应当何时发起网络请求拉取数据。&lt;/p&gt;
&lt;p&gt;在叙述何时拉取数据之前，我们可以先了解一下 React 组件的生命周期，也就是一个 React 组件从构建到解构的全过程：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;准备挂载，这个时候属性会被传递到组件的构造函数之中，实例化一个组件，同时创设相应的 &lt;code&gt;state&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;挂载组件，这个时候框架调用 &lt;code&gt;render&lt;/code&gt; 函数，生成组件的展示方式并渲染，&lt;strong&gt;挂载完毕之后会使用 &lt;code&gt;React.Component&lt;/code&gt; 类之中定义的 &lt;code&gt;componentDidMount&lt;/code&gt; 生命周期方法&lt;/strong&gt;，表示组件挂载完毕。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;监听组件的 &lt;code&gt;setState&lt;/code&gt; 方法调用，一旦组件的状态改变，就代表着可能会导致组件的显示方式改变，此时框架会重新调用 &lt;code&gt;render&lt;/code&gt; 函数进行重新渲染。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;卸载组件，当组件需要被移除的时候，&lt;strong&gt;在卸载之前会调用 &lt;code&gt;React.Component&lt;/code&gt; 类之中定义的 &lt;code&gt;componentWillUnmount&lt;/code&gt; 生命周期方法&lt;/strong&gt;，表示即将卸载组件。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;注意这里提到的 &lt;code&gt;componentDidMount&lt;/code&gt; 和 &lt;code&gt;componentWillUnmount&lt;/code&gt; 方法，这两个方法会在对应的生命周期时间点由 React 框架自动调用。前者调用时组件已经构建完毕且挂载到 DOM 树上，此时便可以从网络拉取数据并写入对应的成员变量或者调用 &lt;code&gt;this.setState&lt;/code&gt; 根据获取的数据重新渲染组件。&lt;/p&gt;
&lt;p&gt;而后者调用时意味着组件即将卸载，此时应当清除掉一些即将不使用的、在后台运行占用资源的计时器、事件监听器等对象，保证资源不浪费。&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt;更完整的生命周期&lt;/summary&gt;
&lt;p&gt;**【注意】**这里可能包含过时乃至危险的编码方法，如果只需要学习生命周期方法的运用可以跳过，本部分仅用于深入了解 React 框架。&lt;/p&gt;
&lt;p&gt;如果使用 VS Code 等带有代码提示的工具编写代码，我们可以看到还有很多其他的生命周期方法：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.clearsec.org/wikis/skills/static/frontend/react/lifecycle-methods.png" alt=""&gt;&lt;/p&gt;
&lt;p&gt;这些方法实际上描述了更为细致的 React 组件生命周期，现在我们逐步表述。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;组件挂载
&lt;ul&gt;
&lt;li&gt;首先调用构造函数 &lt;code&gt;constructor()&lt;/code&gt;，其接受的参数为组件属性，同时初始化组件状态。在 ES6 JavaScript 类语法糖出现之前，构造函数由 &lt;code&gt;getDefaultProps()&lt;/code&gt; 和 &lt;code&gt;getInitialState()&lt;/code&gt; 两个方法替代&lt;/li&gt;
&lt;li&gt;其次调用 &lt;code&gt;componentWillMount()&lt;/code&gt; 方法，用户可以 override 该方法实现自定义功能&lt;/li&gt;
&lt;li&gt;然后调用 &lt;code&gt;render()&lt;/code&gt; 方法获取组件的显示方式，渲染组件&lt;/li&gt;
&lt;li&gt;最后调用 &lt;code&gt;componentDidMount()&lt;/code&gt; 方法，用户可以 override 该方法实现自定义功能&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;组件更新
&lt;ul&gt;
&lt;li&gt;如果是接受新的组件属性进行更新，调用 &lt;code&gt;componentWillReceiveProps()&lt;/code&gt; 方法。该方法接受的参数为该组件的新属性&lt;/li&gt;
&lt;li&gt;首先调用 &lt;code&gt;shouldComponentUpdate()&lt;/code&gt; 方法，该方法返回布尔值，表示组件此时是否需要更新。若得到 &lt;code&gt;false&lt;/code&gt;，则组件停止更新，否则继续向下执行。该方法接受的参数为该组件的新属性和新状态&lt;/li&gt;
&lt;li&gt;其次调用 &lt;code&gt;componentWillUpdate()&lt;/code&gt; 方法，用户可以 override 该方法实现自定义功能。该方法接受的参数为该组件的新属性和新状态&lt;/li&gt;
&lt;li&gt;然后调用 &lt;code&gt;render()&lt;/code&gt; 方法获取组件显示方式，渲染组件&lt;/li&gt;
&lt;li&gt;最后调用 &lt;code&gt;componentDidUpdate()&lt;/code&gt; 方法，表示组件更新完毕。该方法接受的参数为组件更新前的旧属性和旧状态&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;组件卸载
&lt;ul&gt;
&lt;li&gt;调用 &lt;code&gt;componentWillUnmount()&lt;/code&gt; 方法，用户可以 override 该方法实现自定义功能&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;组件错误处理
&lt;ul&gt;
&lt;li&gt;调用 &lt;code&gt;componentDidCatch()&lt;/code&gt; 方法，用户可以 override 该方法实现自定义功能。该方法接受的参数为错误信息&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;组件监听的方法调用
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;setState()&lt;/code&gt; 方法发起组件更新的&lt;strong&gt;请求&lt;/strong&gt;，会触发一次重新渲染，具体用法先前已经讲解&lt;/li&gt;
&lt;li&gt;&lt;code&gt;forceUpdate()&lt;/code&gt; 方法发起组件更新的&lt;strong&gt;命令&lt;/strong&gt;，与 &lt;code&gt;setState()&lt;/code&gt; 方法不同在其会无视 &lt;code&gt;componentShouldUpdate()&lt;/code&gt; 的返回值，正常完成组件更新流程（包括调用 &lt;code&gt;componentDidUpdate()&lt;/code&gt; 方法）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;总体而言，React 组件的生命周期大致为下图（ES5 版本，不包括组件错误处理和方法监听）：&lt;/p&gt;</description></item><item><title>非常规数据流</title><link>https://www.clearsec.org/wikis/skills/frontend/react/dataflow/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.clearsec.org/wikis/skills/frontend/react/dataflow/</guid><description>&lt;h1 id="非常规数据流"&gt;非常规数据流&lt;/h1&gt;
&lt;p&gt;我们先前介绍过 React 的瀑布数据流，也就是父组件向子组件传递数据的数据组织形式。但是有时我们会要求子组件的行为影响父组件，或者多个组件之间共享信息。本部分将会简要介绍如何实现这些非常规数据流。&lt;/p&gt;
&lt;h2 id="反向数据流"&gt;反向数据流&lt;/h2&gt;
&lt;p&gt;反向数据流实际上是一个很常见的需求，比如说&lt;strong&gt;分页器&lt;/strong&gt;。分页器在 UI 构成上而言，仅仅是一个网页的部分，但是它的状态却决定了整个网页应当显示的内容。从而我们必须构建从分页器向父组件的数据流，让分页器起到作用。&lt;/p&gt;
&lt;p&gt;这里我们沿用先前的代码，考虑一个简化的反向数据流需求。比如说这里，我们希望让点击正方形这个事件，不仅仅改变正方形本身的颜色，还可以改变父组件 &lt;code&gt;App&lt;/code&gt; 内部的计数器来显示点击次数。&lt;/p&gt;
&lt;div class="td-alert td-alert--md alert alert-note" role="alert"&gt;&lt;div class="td-alert-heading alert-heading" role="heading"&gt;说明&lt;/div&gt;
 &lt;div class="td-alert-body"&gt;
 &lt;p&gt;&lt;strong&gt;删掉一些多余的代码&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这里我们不涉及生命周期，故可以删除掉 &lt;code&gt;Square&lt;/code&gt; 组件内的计时器以及相关的生命周期代码。
首先我们需要在父组件 &lt;code&gt;App&lt;/code&gt; 的状态中添加一个计数器，并且在构造函数中初始化。修改后的 &lt;code&gt;App&lt;/code&gt; 组件为：&lt;/p&gt;
 &lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Component &amp;#39;App&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;AppState&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;clickCnt&lt;/span&gt;: &lt;span class="kt"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="kr"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;Record&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;never&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;,&lt;/span&gt; &lt;span class="na"&gt;AppState&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;: &lt;span class="kt"&gt;Record&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;never&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;clickCnt&lt;/span&gt;: &lt;span class="kt"&gt;0&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ReactElement&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;This&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;square&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;We&lt;/span&gt; &lt;span class="nx"&gt;have&lt;/span&gt; &lt;span class="nx"&gt;click&lt;/span&gt; &lt;span class="nx"&gt;it&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clickCnt&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;Square&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;red&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;details&gt;
&lt;summary&gt;`Record&lt;string, never&gt;` 是什么？&lt;/summary&gt;
&lt;p&gt;&lt;code&gt;Record&amp;lt;string, never&amp;gt;&lt;/code&gt; 可以理解为空对象 &lt;code&gt;{}&lt;/code&gt; 的类型标注，这里仅仅是为了通过 TypeScript 的类型检查。&lt;/p&gt;
&lt;/details&gt;
此外，我们还需要编写一个递增计数器的成员函数：
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Component &amp;#39;App&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;increaseCnter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;clickCnt&lt;/span&gt;: &lt;span class="kt"&gt;prev.clickCnt&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;现在我们需要思考的就是如何让子组件 &lt;code&gt;Square&lt;/code&gt; 调用到这个函数。我们注意到在 TypeScript 语言之中，函数也是一种对象，所以我们完全可以通过组件属性将这个函数传递给子组件。那么我们需要在子组件属性接口上增添一个回调函数：&lt;/p&gt;</description></item><item><title>函数组件</title><link>https://www.clearsec.org/wikis/skills/frontend/react/function-component/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.clearsec.org/wikis/skills/frontend/react/function-component/</guid><description>&lt;h1 id="函数组件"&gt;函数组件&lt;/h1&gt;
&lt;p&gt;我们通过类组件简单介绍了 React 的核心概念，但是类组件有下述比较明显的问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;编码繁琐，尤其在使用 TypeScript 语言的时候&lt;/li&gt;
&lt;li&gt;可能会出现 &lt;code&gt;this&lt;/code&gt; 的指向不明确的问题&lt;/li&gt;
&lt;li&gt;JavaScript 语言的类语法仅仅是语法糖，并非是完全符合面向对象思路的&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以在新版本的 React 框架中，我们更为推荐大家编写函数组件。&lt;/p&gt;
&lt;p&gt;函数组件的基本思维是将整个组件思考为函数，函数的参数为组件的属性，而返回值就是组件的显示方式（即类组件的 &lt;code&gt;render&lt;/code&gt; 函数返回值）。也就是说，将组件视作一种接收属性，获取组件渲染指示的数据流管道更为可行。这种思路下开发者可以简单地组合各种管道来实现 Web 应用。&lt;/p&gt;
&lt;p&gt;比如说下述没有设置组件状态的、没有使用生命周期方法的正方形组件：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;SquareProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;size&lt;/span&gt;: &lt;span class="kt"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;: &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Square&lt;/span&gt; &lt;span class="kr"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;SquareProps&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ReactElement&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;width&lt;/span&gt;: &lt;span class="kt"&gt;this.props.size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;height&lt;/span&gt;: &lt;span class="kt"&gt;this.props.size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;backgroundColor&lt;/span&gt;: &lt;span class="kt"&gt;this.props.color&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;就可以转写为下述函数组件：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;SquareProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;size&lt;/span&gt;: &lt;span class="kt"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;: &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Square&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;: &lt;span class="kt"&gt;SquareProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ReactElement&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;width&lt;/span&gt;: &lt;span class="kt"&gt;props.size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;height&lt;/span&gt;: &lt;span class="kt"&gt;props.size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;backgroundColor&lt;/span&gt;: &lt;span class="kt"&gt;props.color&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这样的转写并不改变组件的本质，使用该组件的方式也和类组件一致。&lt;/p&gt;
&lt;h2 id="hooks-简要介绍"&gt;Hooks 简要介绍&lt;/h2&gt;
&lt;p&gt;在转写上述类组件的时候，我们注意到如果组件具有状态或者使用了生命周期方法，则无法转写。这里，React 提供的解决方式是使用 Hooks。&lt;/p&gt;
&lt;h3 id="管理组件状态"&gt;管理组件状态&lt;/h3&gt;
&lt;p&gt;我们首先介绍管理状态需要使用的 Hooks，即 &lt;code&gt;useState&lt;/code&gt; 函数。比如说我们依然是将正方形的颜色变为其状态，由组件自身管理，其代码大致为：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;SquareProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;size&lt;/span&gt;: &lt;span class="kt"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;: &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Square&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;: &lt;span class="kt"&gt;SquareProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ReactElement&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setColor&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;switchColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;setColor&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;prev&lt;/span&gt;: &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;prev&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;red&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;blue&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;red&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;width&lt;/span&gt;: &lt;span class="kt"&gt;props.size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;height&lt;/span&gt;: &lt;span class="kt"&gt;props.size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;backgroundColor&lt;/span&gt;: &lt;span class="kt"&gt;color&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;switchColor&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这里高亮的三行表现出使用 Hooks 的时候需要修改的地方。首先注意第 7 行，这里使用了 &lt;code&gt;useState&lt;/code&gt; 函数，该函数接受的是需要设定的状态的初始值，返回的是该状态和用于设定该状态的函数。这里我们设定的状态为 &lt;code&gt;color&lt;/code&gt;，初始值为 &lt;code&gt;props.color&lt;/code&gt;，而 &lt;code&gt;setColor&lt;/code&gt; 和类组件之中的 &lt;code&gt;setState&lt;/code&gt; 类似，用于修改状态。&lt;/p&gt;</description></item><item><title>后续拓展</title><link>https://www.clearsec.org/wikis/skills/frontend/react/extensions/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.clearsec.org/wikis/skills/frontend/react/extensions/</guid><description>&lt;h1 id="后续拓展"&gt;后续拓展&lt;/h1&gt;
&lt;p&gt;如果你已经学习完了这一篇文档，理解了我们讲述的所有概念，那么你就已经有足够的能力完成《软件工程》课程的大作业 Web 应用前端，乃至开发出一个真正可以上架的 Web 应用了！剩下的，仅仅是多多练习，在编程中理解这些概念，运用这些概念。&lt;/p&gt;
&lt;p&gt;不过在真正踏上 Web 前端的道路之前，我们还有一些可以给出的资源链接。&lt;/p&gt;
&lt;h2 id="ant-design"&gt;Ant Design&lt;/h2&gt;
&lt;p&gt;Ant Design 是一个成熟的前端组件库，其作用在于免去调试一整天 CSS 样式表还调不出好看的 Layout 或灵活的交互的苦恼，让我们能更专注于设计前端和用户、后端、数据库的交互逻辑和前端性能。&lt;/p&gt;
&lt;p&gt;Ant Design 官方网址：&lt;a href="https://ant.design/index-cn"&gt;https://ant.design/index-cn&lt;/a&gt;。&lt;/p&gt;</description></item></channel></rss>