共计 12454 个字符,预计需要花费 32 分钟才能阅读完成。
hooks 为什么不能放在条件判断里
以 setState 为例,在 react 外部,每个组件 (Fiber) 的 hooks 都是以链表的模式存在 memoizeState 属性中
update 阶段,每次调用 setState,链表就会执行 next 向后挪动一步。如果将 setState 写在条件判断中,假如条件判断不成立,没有执行外面的 setState 办法,会导致接下来所有的 setState 的取值呈现偏移,从而导致异样产生。
React 高阶组件、Render props、hooks 有什么区别,为什么要一直迭代
这三者是目前 react 解决代码复用的次要形式:
- 高阶组件(HOC)是 React 中用于复用组件逻辑的一种高级技巧。HOC 本身不是 React API 的一部分,它是一种基于 React 的组合个性而造成的设计模式。具体而言,高阶组件是参数为组件,返回值为新组件的函数。
- render props 是指一种在 React 组件之间应用一个值为函数的 prop 共享代码的简略技术,更具体的说,render prop 是一个用于告知组件须要渲染什么内容的函数 prop。
- 通常,render props 和高阶组件只渲染一个子节点。让 Hook 来服务这个应用场景更加简略。这两种模式仍有用武之地,(例如,一个虚构滚动条组件或者会有一个 renderltem 属性,或是一个可见的容器组件或者会有它本人的 DOM 构造)。但在大部分场景下,Hook 足够了,并且可能帮忙缩小嵌套。
(1)HOC 官网解释∶
高阶组件(HOC)是 React 中用于复用组件逻辑的一种高级技巧。HOC 本身不是 React API 的一部分,它是一种基于 React 的组合个性而造成的设计模式。
简言之,HOC 是一种组件的设计模式,HOC 承受一个组件和额定的参数(如果须要),返回一个新的组件。HOC 是纯函数,没有副作用。
// hoc 的定义
function withSubscription(WrappedComponent, selectData) {
return class extends React.Component {constructor(props) {super(props);
this.state = {data: selectData(DataSource, props)
};
}
// 一些通用的逻辑解决
render() {
// ... 并应用新数据渲染被包装的组件!
return <WrappedComponent data={this.state.data} {...this.props} />;
}
};
// 应用
const BlogPostWithSubscription = withSubscription(BlogPost,
(DataSource, props) => DataSource.getBlogPost(props.id));
HOC 的优缺点∶
- 长处∶ 逻辑服用、不影响被包裹组件的外部逻辑。
- 毛病∶ hoc 传递给被包裹组件的 props 容易和被包裹后的组件重名,进而被笼罩
(2)Render props 官网解释∶
“render prop” 是指一种在 React 组件之间应用一个值为函数的 prop 共享代码的简略技术
具备 render prop 的组件承受一个返回 React 元素的函数,将 render 的渲染逻辑注入到组件外部。在这里,”render” 的命名能够是任何其余无效的标识符。
// DataProvider 组件外部的渲染逻辑如下
class DataProvider extends React.Components {
state = {name: 'Tom'}
render() {
return (
<div>
<p> 共享数据组件本人外部的渲染逻辑 </p>
{this.props.render(this.state) } </div>
);
}
}
// 调用形式
<DataProvider render={data => (<h1>Hello {data.name}</h1>
)}/>
由此能够看到,render props 的优缺点也很显著∶
- 长处:数据共享、代码复用,将组件内的 state 作为 props 传递给调用者,将渲染逻辑交给调用者。
- 毛病:无奈在 return 语句外拜访数据、嵌套写法不够优雅
(3)Hooks 官网解释∶
Hook 是 React 16.8 的新增个性。它能够让你在不编写 class 的状况下应用 state 以及其余的 React 个性。通过自定义 hook,能够复用代码逻辑。
// 自定义一个获取订阅数据的 hook
function useSubscription() {const data = DataSource.getComments();
return [data];
}
//
function CommentList(props) {const {data} = props;
const [subData] = useSubscription();
...
}
// 应用
<CommentList data='hello' />
以上能够看出,hook 解决了 hoc 的 prop 笼罩的问题,同时应用的形式解决了 render props 的嵌套天堂的问题。hook 的长处如下∶
- 应用直观;
- 解决 hoc 的 prop 重名问题;
- 解决 render props 因共享数据 而呈现嵌套天堂的问题;
- 能在 return 之外应用数据的问题。
须要留神的是:hook 只能在组件顶层应用,不可在分支语句中应用。、
React 中能够在 render 拜访 refs 吗?为什么?
<>
<span id="name" ref={this.spanRef}>{this.state.title}</span>
<span>{this.spanRef.current ? '有值' : '无值'}</span>
</>
不能够,render 阶段 DOM 还没有生成,无奈获取 DOM。DOM 的获取须要在 pre-commit 阶段和 commit 阶段:
Component, Element, Instance 之间有什么区别和分割?
- 元素: 一个元素
element
是一个一般对象 (plain object),形容了对于一个 DOM 节点或者其余组件component
,你想让它在屏幕上出现成什么样子。元素element
能够在它的属性props
中蕴含其余元素 (译注: 用于造成元素树)。创立一个 React 元素element
老本很低。元素element
创立之后是不可变的。 - 组件: 一个组件
component
能够通过多种形式申明。能够是带有一个render()
办法的类,简略点也能够定义为一个函数。这两种状况下,它都把属性props
作为输出,把返回的一棵元素树作为输入。 - 实例: 一个实例
instance
是你在所写的组件类component class
中应用关键字this
所指向的货色(译注: 组件实例)。它用来存储本地状态和响应生命周期事件很有用。
函数式组件 (Functional component
) 基本没有实例 instance
。类组件(Class component
) 有实例instance
,然而永远也不须要间接创立一个组件的实例,因为 React 帮咱们做了这些。
state 和 props 区别是啥?
- state 是组件本人治理数据,管制本人的状态,可变;
- props 是内部传入的数据参数,不可变;
- 没有 state 的叫做无状态组件,有 state 的叫做有状态组件;
- 多用 props,少用 state,也就是多写无状态组件。
React 中发动网络申请应该在哪个生命周期中进行?为什么?
对于异步申请,最好放在 componentDidMount 中去操作,对于同步的状态扭转,能够放在 componentWillMount 中,个别用的比拟少。
如果认为在 componentWillMount 里发动申请能提前取得后果,这种想法其实是谬误的,通常 componentWillMount 比 componentDidMount 早不了多少微秒,网络上任何一点提早,这一点差别都可忽略不计。
react 的生命周期: constructor() -> componentWillMount() -> render() -> componentDidMount()
下面这些办法的调用是有秩序的,由上而下顺次调用。
- constructor 被调用是在组件筹备要挂载的最开始,此时组件尚未挂载到网页上。
- componentWillMount 办法的调用在 constructor 之后,在 render 之前,在这办法里的代码调用 setState 办法不会触发从新 render,所以它个别不会用来作加载数据之用。
- componentDidMount 办法中的代码,是在组件曾经齐全挂载到网页上才会调用被执行,所以能够保证数据的加载。此外,在这办法中调用 setState 办法,会触发从新渲染。所以,官网设计这个办法就是用来加载内部数据用的,或解决其余的副作用代码。与组件上的数据无关的加载,也能够在 constructor 里做,但 constructor 是做组件 state 初绐化工作,并不是做加载数据这工作的,constructor 里也不能 setState,还有加载的工夫太长或者出错,页面就无奈加载进去。所以有副作用的代码都会集中在 componentDidMount 办法里。
总结:
- 跟服务器端渲染(同构)有关系,如果在 componentWillMount 外面获取数据,fetch data 会执行两次,一次在服务器端一次在客户端。在 componentDidMount 中能够解决这个问题,componentWillMount 同样也会 render 两次。
- 在 componentWillMount 中 fetch data,数据肯定在 render 后能力达到,如果遗记了设置初始状态,用户体验不好。
- react16.0 当前,componentWillMount 可能会被执行屡次。
参考 前端进阶面试题具体解答
如何解决 props 层级过深的问题
- 应用 Context API:提供一种组件之间的状态共享,而不用通过显式组件树逐层传递 props;
- 应用 Redux 等状态库。
对 React SSR 的了解
服务端渲染是数据与模版组成的 html,即 HTML = 数据 + 模版。将组件或页面通过服务器生成 html 字符串,再发送到浏览器,最初将动态标记 ” 混合 ” 为客户端上齐全交互的应用程序。页面没应用服务渲染,当申请页面时,返回的 body 里为空,之后执行 js 将 html 构造注入到 body 里,联合 css 显示进去;
SSR 的劣势:
- 对 SEO 敌对
- 所有的模版、图片等资源都存在服务器端
- 一个 html 返回所有数据
- 缩小 HTTP 申请
- 响应快、用户体验好、首屏渲染快
1)更利于 SEO
不同爬虫工作原理相似,只会爬取源码,不会执行网站的任何脚本应用了 React 或者其它 MVVM 框架之后,页面大多数 DOM 元素都是在客户端依据 js 动静生成,可供爬虫抓取剖析的内容大大减少。另外,浏览器爬虫不会期待咱们的数据实现之后再去抓取页面数据。服务端渲染返回给客户端的是曾经获取了异步数据并执行 JavaScript 脚本的最终 HTML,网络爬中就能够抓取到残缺页面的信息。
2)更利于首屏渲染
首屏的渲染是 node 发送过去的 html 字符串,并不依赖于 js 文件了,这就会使用户更快的看到页面的内容。尤其是针对大型单页利用,打包后文件体积比拟大,一般客户端渲染加载所有所需文件工夫较长,首页就会有一个很长的白屏等待时间。
SSR 的局限:
1)服务端压力较大
原本是通过客户端实现渲染,当初对立到服务端 node 服务去做。尤其是高并发拜访的状况,会大量占用服务端 CPU 资源;
2)开发条件受限
在服务端渲染中,只会执行到 componentDidMount 之前的生命周期钩子,因而我的项目援用的第三方的库也不可用其它生命周期钩子,这对援用库的抉择产生了很大的限度;
3)学习老本绝对较高 除了对 webpack、MVVM 框架要相熟,还须要把握 node、Koa2 等相干技术。绝对于客户端渲染,我的项目构建、部署过程更加简单。
工夫耗时比拟:
1)数据申请
由服务端申请首屏数据,而不是客户端申请首屏数据,这是 ” 快 ” 的一个次要起因。服务端在内网进行申请,数据响应速度快。客户端在不同网络环境进行数据申请,且外网 http 申请开销大,导致时间差
- 客户端数据申请
-
服务端数据申请
2)html 渲染 服务端渲染是先向后端服务器申请数据,而后生成残缺首屏 html 返回给浏览器;而客户端渲染是等 js 代码下载、加载、解析实现后再申请数据渲染,期待的过程页面是什么都没有的,就是用户看到的白屏。就是服务端渲染不须要期待 js 代码下载实现并申请数据,就能够返回一个已有残缺数据的首屏页面。
- 非 ssr html 渲染
- ssr html 渲染
能够应用 TypeScript 写 React 利用吗?怎么操作?
(1)如果还未创立 Create React App 我的项目
- 间接创立一个具备 typescript 的 Create React App 我的项目:
npx create-react-app demo --typescript
(2)如果曾经创立了 Create React App 我的项目,须要将 typescript 引入到已有我的项目中
- 通过命令将 typescript 引入我的项目:
npm install --save typescript @types/node @types/react @types/react-dom @types/jest
- 将我的项目中任何 后缀名为‘.js’的 JavaScript 文件重命名为 TypeScript 文件即后缀名为‘.tsx’(例如 src/index.js 重命名为 src/index.tsx)
React key 是干嘛用的 为什么要加?key 次要是解决哪一类问题的
Keys 是 React 用于追踪哪些列表中元素被批改、被增加或者被移除的辅助标识。在开发过程中,咱们须要保障某个元素的 key 在其同级元素中具备唯一性。
在 React Diff 算法中 React 会借助元素的 Key 值来判断该元素是早先创立的还是被挪动而来的元素,从而缩小不必要的元素重渲染此外,React 还须要借助 Key 值来判断元素与本地状态的关联关系。
注意事项:
- key 值肯定要和具体的元素—一对应;
- 尽量不要用数组的 index 去作为 key;
- 不要在 render 的时候用随机数或者其余操作给元素加上不稳固的 key,这样造成的性能开销比不加 key 的状况下更蹩脚。
React 中怎么测验 props?验证 props 的目标是什么?
React为咱们提供了 PropTypes 以供验证应用。当咱们向 Props 传入的数据有效(向 Props 传入的数据类型和验证的数据类型不符)就会在控制台收回正告信息。它能够防止随着利用越来越简单从而呈现的问题。并且,它还能够让程序变得更易读。
import PropTypes from 'prop-types';
class Greeting extends React.Component {render() {
return (<h1>Hello, {this.props.name}</h1>
);
}
}
Greeting.propTypes = {name: PropTypes.string};
当然,如果我的项目汇中应用了 TypeScript,那么就能够不必 PropTypes 来校验,而应用 TypeScript 定义接口来校验 props。
React 组件命名举荐的形式是哪个?
通过援用而不是应用来命名组件 displayName。
应用 displayName 命名组件:
export default React.createClass({displayName: 'TodoApp', // ...})
React 举荐的办法:
export default class TodoApp extends React.Component {// ...}
react 父子传值
父传子——在调用子组件上绑定,子组件中获取 this.props
子传父——援用子组件的时候传过来一个办法,子组件通过 this.props.methed()传过来参数
connection
React 16 中新生命周期有哪些
对于 React16 开始利用的新生命周期:能够看出,React16 自上而下地对生命周期做了另一种维度的解读:
- Render 阶段:用于计算一些必要的状态信息。这个阶段可能会被 React 暂停,这一点和 React16 引入的 Fiber 架构(咱们前面会重点解说)是无关的;
- Pre-commit 阶段:所谓“commit”,这里指的是“更新真正的 DOM 节点”这个动作。所谓 Pre-commit,就是说我在这个阶段其实还并没有去更新实在的 DOM,不过 DOM 信息曾经是能够读取的了;
- Commit 阶段:在这一步,React 会实现实在 DOM 的更新工作。Commit 阶段,咱们能够拿到实在 DOM(包含 refs)。
与此同时,新的生命周期在流程方面,依然遵循“挂载”、“更新”、“卸载”这三个狭义的划分形式。它们别离对应到:
-
挂载过程:
- constructor
- getDerivedStateFromProps
- render
- componentDidMount
-
更新过程:
- getDerivedStateFromProps
- shouldComponentUpdate
- render
- getSnapshotBeforeUpdate
- componentDidUpdate
-
卸载过程:
- componentWillUnmount
react 最新版本解决了什么问题,减少了哪些货色
React 16.x 的三大新个性 Time Slicing、Suspense、hooks
- Time Slicing(解决 CPU 速度问题)使得在执行工作的期间能够随时暂停,跑去干别的事件,这个个性使得 react 能在性能极其差的机器跑时,依然放弃有良好的性能
- Suspense(解决网络 IO 问题) 和 lazy 配合,实现异步加载组件。能暂停以后组件的渲染,当实现某件事当前再持续渲染,解决从 react 出世到当初都存在的「异步副作用」的问题,而且解决得非的优雅,应用的是 T 异步然而同步的写法,这是最好的解决异步问题的形式
- 提供了一个 内置函数 componentDidCatch,当有谬误产生时,能够敌对地展现 fallback 组件; 能够捕捉到它的子元素(包含嵌套子元素)抛出的异样; 能够复用谬误组件。
(1)React16.8 退出 hooks,让 React 函数式组件更加灵便,hooks 之前,React 存在很多问题:
- 在组件间复用状态逻辑很难
- 简单组件变得难以了解,高阶组件和函数组件的嵌套过深。
- class 组件的 this 指向问题
- 难以记忆的生命周期
hooks 很好的解决了上述问题,hooks 提供了很多办法
- useState 返回有状态值,以及更新这个状态值的函数
- useEffect 承受蕴含命令式,可能有副作用代码的函数。
- useContext 承受上下文对象(从 React.createContext 返回的值)并返回以后上下文值,
- useReducer useState 的代替计划。承受类型为(state,action)=> newState 的 reducer,并返回与 dispatch 办法配对的以后状态。
- useCalLback 返回一个回顾的 memoized 版本,该版本仅在其中一个输出产生更改时才会更改。纯函数的输入输出确定性 o useMemo 纯的一个记忆函数 o useRef 返回一个可变的 ref 对象,其 Current 属性被初始化为传递的参数,返回的 ref 对象在组件的整个生命周期内放弃不变。
- useImperativeMethods 自定义应用 ref 时公开给父组件的实例值
- useMutationEffect 更新兄弟组件之前,它在 React 执行其 DOM 扭转的同一阶段同步触发
- useLayoutEffect DOM 扭转后同步触发。应用它来从 DOM 读取布局并同步从新渲染
(2)React16.9
- 重命名 Unsafe 的生命周期办法。新的 UNSAFE_前缀将有助于在代码 review 和 debug 期间,使这些有问题的字样更突出
- 废除 javascrip: 模式的 URL。以 javascript: 结尾的 URL 非常容易蒙受攻打,造成安全漏洞。
- 废除 ”Factory” 组件。工厂组件会导致 React 变大且变慢。
- act()也反对异步函数,并且你能够在调用它时应用 await。
- 应用 <React.ProfiLer> 进行性能评估。在较大的利用中追踪性能回归可能会很不便
(3)React16.13.0
- 反对在渲染期间调用 setState,但仅实用于同一组件
- 可检测抵触的款式规定并记录正告
- 废除 unstable_createPortal,应用 CreatePortal
- 将组件堆栈增加到其开发正告中,使开发人员可能隔离 bug 并调试其程序,这能够分明地阐明问题所在,并更快地定位和修复谬误。
React 组件的 state 和 props 有什么区别?
(1)props
props 是一个从内部传进组件的参数,次要作为就是从父组件向子组件传递数据,它具备可读性和不变性,只能通过内部组件被动传入新的 props 来从新渲染子组件,否则子组件的 props 以及展示模式不会扭转。
(2)state
state 的次要作用是用于组件保留、管制以及批改本人的状态,它只能在 constructor 中初始化,它算是组件的公有属性,不可通过内部拜访和批改,只能通过组件外部的 this.setState 来批改,批改 state 属性会导致组件的从新渲染。
(3)区别
- props 是传递给组件的(相似于函数的形参),而 state 是在组件内被组件本人治理的(相似于在一个函数内申明的变量)。
- props 是不可批改的,所有 React 组件都必须像纯函数一样爱护它们的 props 不被更改。
- state 是在组件中创立的,个别在 constructor 中初始化 state。state 是多变的、能够批改,每次 setState 都异步更新的。
react-router 里的 Link 标签和 a 标签的区别
从最终渲染的 DOM 来看,这两者都是链接,都是 标签,区别是∶ <Link>
是 react-router 里实现路由跳转的链接,个别配合 <Route>
应用,react-router 接管了其默认的链接跳转行为,区别于传统的页面跳转,<Link>
的“跳转”行为只会触发相匹配的<Route>
对应的页面内容更新,而不会刷新整个页面。
<Link>
做了 3 件事件:
- 有 onclick 那就执行 onclick
- click 的时候阻止 a 标签默认事件
- 依据跳转 href(即是 to),用 history (web 前端路由两种形式之一,history & hash)跳转,此时只是链接变了,并没有刷新页面而
<a>
标签就是一般的超链接了,用于从以后页面跳转到 href 指向的另一 个页面(非锚点状况)。
a 标签默认事件禁掉之后做了什么才实现了跳转?
let domArr = document.getElementsByTagName('a')
[...domArr].forEach(item=>{item.addEventListener('click',function () {location.href = this.href})
})
react 生命周期
初始化阶段:
- getDefaultProps: 获取实例的默认属性
- getInitialState: 获取每个实例的初始化状态
- componentWillMount:组件行将被装载、渲染到页面上
- render: 组件在这里生成虚构的 DOM 节点
- componentDidMount: 组件真正在被装载之后
运行中状态:
- componentWillReceiveProps: 组件将要接管到属性的时候调用
- shouldComponentUpdate: 组件承受到新属性或者新状态的时候(能够返回 false,接收数据后不更新,阻止 render 调用,前面的函数不会被继续执行了)
- componentWillUpdate: 组件行将更新不能批改属性和状态
- render: 组件从新描述
- componentDidUpdate: 组件曾经更新
销毁阶段:
- componentWillUnmount: 组件行将销毁
shouldComponentUpdate 是做什么的,(react 性能优化是哪个周期函数?)
shouldComponentUpdate 这个办法用来判断是否须要调用 render 办法从新描述 dom。因为 dom 的描述十分耗费性能,如果咱们能在 shouldComponentUpdate 办法中可能写出更优化的 dom diff 算法,能够极大的进步性能。
在 react17 会删除以下三个生命周期
componentWillMount,componentWillReceiveProps,componentWillUpdate
react router
import React from 'react'
import {render} from 'react-dom'
import {browserHistory, Router, Route, IndexRoute} from 'react-router'
import App from '../components/App'
import Home from '../components/Home'
import About from '../components/About'
import Features from '../components/Features'
render(<Router history={browserHistory}> // history 路由
<Route path='/' component={App}>
<IndexRoute component={Home} />
<Route path='about' component={About} />
<Route path='features' component={Features} />
</Route>
</Router>,
document.getElementById('app')
)
render(<Router history={browserHistory} routes={routes} />,
document.getElementById('app')
)
React Router 提供一个 routerWillLeave 生命周期钩子,这使得 React 组件能够拦挡正在产生的跳转,或在来到 route 前提醒用户。routerWillLeave 返回值有以下两种:
return
false
勾销此次跳转 return
返回提示信息,在来到 route 前提醒用户进行确认。
对 React Hook 的了解,它的实现原理是什么
React-Hooks 是 React 团队在 React 组件开发实际中,逐步认知到的一个改良点,这背地其实波及对 类组件 和函数组件 两种组件模式的思考和偏重。
(1)类组件: 所谓类组件,就是基于 ES6 Class 这种写法,通过继承 React.Component 得来的 React 组件。以下是一个类组件:
class DemoClass extends React.Component {
state = {text: ""};
componentDidMount() {//...}
changeText = (newText) => {
this.setState({text: newText});
};
render() {
return (
<div className="demoClass">
<p>{this.state.text}</p>
<button onClick={this.changeText}> 批改 </button>
</div>
);
}
}
能够看出,React 类组件外部预置了相当多的“现成的货色”等着咱们去调度 / 定制,state 和生命周期就是这些“现成货色”中的典型。要想得到这些货色,难度也不大,只须要继承一个 React.Component 即可。
当然,这也是类组件的一个不便,它太繁冗了,对于解决许多问题来说,编写一个类组件切实是一个过于简单的姿态。简单的姿态必然带来昂扬的了解老本,这也是咱们所不想看到的。除此之外,因为开发者编写的逻辑在封装后是和组件粘在一起的,这就使得 类组件外部的逻辑难以实现拆分和复用。
(2)函数组件:函数组件就是以函数的状态存在的 React 组件。晚期并没有 React-Hooks,函数组件外部无奈定义和保护 state,因而它还有一个别名叫“无状态组件”。以下是一个函数组件:
function DemoFunction(props) {const { text} = props
return (
<div className="demoFunction">
<p>{` 函数组件接管的内容:[${text}]`}</p>
</div>
);
}
相比于类组件,函数组件肉眼可见的特质天然包含轻量、灵便、易于组织和保护、较低的学习老本等。
通过比照,从状态上能够对两种组件做辨别,它们之间的区别如下:
- 类组件须要继承 class,函数组件不须要;
- 类组件能够拜访生命周期办法,函数组件不能;
- 类组件中能够获取到实例化后的 this,并基于这个 this 做各种各样的事件,而函数组件不能够;
- 类组件中能够定义并保护 state(状态),而函数组件不能够;
除此之外,还有一些其余的不同。通过下面的区别,咱们不能说谁好谁坏,它们各有本人的劣势。在 React-Hooks 呈现之前,类组件的能力边界显著强于函数组件。
实际上,类组件和函数组件之间,是面向对象和函数式编程这两套不同的设计思维之间的差别。而函数组件更加符合 React 框架的设计理念:React 组件自身的定位就是函数,一个输出数据、输入 UI 的函数。作为开发者,咱们编写的是申明式的代码,而 React 框架的次要工作,就是及时地把申明式的代码转换为命令式的 DOM 操作,把数据层面的形容映射到用户可见的 UI 变动中去。这就意味着从原则上来讲,React 的数据应该总是紧紧地和渲染绑定在一起的,而类组件做不到这一点。函数组件就真正地将数据和渲染绑定到了一起。函数组件是一个更加匹配其设计理念、也更有利于逻辑拆分与重用的组件表达形式。
为了能让开发者更好的的去编写函数式组件。于是,React-Hooks 便应运而生。
React-Hooks 是一套可能使函数组件更弱小、更灵便的“钩子”。
函数组件比起类组件少了很多货色,比方生命周期、对 state 的治理等。这就给函数组件的应用带来了十分多的局限性,导致咱们并不能应用函数这种模式,写出一个真正的全功能的组件。而 React-Hooks 的呈现,就是为了帮忙函数组件补齐这些(绝对于类组件来说)缺失的能力。
如果说函数组件是一台笨重的快艇,那么 React-Hooks 就是一个内容丰盛的零部件箱。“重装战舰”所预置的那些设施,这个箱子里根本全都有,同时它还不强制你全都要,而是容许你自在地抉择和应用你须要的那些能力,而后将这些能力以 Hook(钩子)的模式“钩”进你的组件里,从而定制出一个最适宜你的“专属战舰”。