reactjs-interview-questions - 排名前 500 的 ReactJS 面试问题和答案列表......编码练习题即将推出!

Created at: 2018-06-01 01:17:01
Language: JavaScript

React 面试问题和答案

如果你喜欢该项目,请单击。高度赞赏拉取请求。@SudheerJonna关注我以获取技术更新。


学习编码并通过“从零到精通”获得录用:
  1. 这门 React 课程很好,如果你正在努力学习 React 超越基础知识
  2. 如果你认真考虑被聘为开发人员,这个编码面试训练营会很有帮助

注意:此存储库特定于 ReactJS。请查看 Javascript 面试问题,了解核心 JavaScript 问题。

下载 PDF/Epub 格式

你可以从操作选项卡上的最新运行下载此存储库的 PDF 和 Epub 版本。

目录

不。 问题
核心 React
1 什么是 React ?
2 React 的主要特性是什么?
3 什么是JSX?
4 元素和组件有什么区别?
5 如何在 React 中创建组件?
6 何时使用类组件而不是函数组件?
7 什么是纯组件?
8 React 中的状态是什么?
9 React 中的道具是什么?
10 状态和道具有什么区别?
11 为什么我们不应该直接更新状态?
12 回调函数作为 setState() 的参数的目的是什么?
13 HTML 和 React 事件处理有什么区别?
14 如何在 JSX 回调中绑定方法或事件处理程序?
15 如何将参数传递给事件处理程序或回调?
16 什么是 React 中的合成事件?
17 什么是内联条件表达式?
18 什么是“键”道具,在元素数组中使用它有什么好处?
19 引用有什么用?
20 如何创建引用?
21 什么是前向引用?
22 回调引用和 findDOMNode() 哪个是首选选项?
23 为什么字符串引用是遗留的?
24 什么是虚拟 DOM?
25 虚拟 DOM 如何工作?
26 Shadow DOM和Virtual DOM有什么区别?
27 什么是 React Fiber?
28 React Fiber 的主要目标是什么?
29 什么是受控组件?
30 什么是不受控制的组件?
31 createElement 和 cloneElement 有什么区别?
32 什么是在 React 中提升状态?
33 组件生命周期有哪些不同阶段?
34 React 的生命周期方法是什么?
35 什么是高阶组件?
36 如何为 HOC 组件创建道具代理?
37 什么是上下文?
38 什么是儿童道具?
39 如何在 React 中写评论?
40 使用带有道具参数的超级构造函数的目的是什么?
41 什么是和解?
42 如何使用动态键名称设置状态?
43 每次组件渲染时调用函数的常见错误是什么?
44 惰性函数是否支持命名导出?
45 为什么 React 在类属性上使用类名?
46 什么是片段?
47 为什么片段比容器 div 更好?
48 什么是 React 中的门户?
49 什么是无状态组件?
50 什么是有状态组件?
51 如何在 React 中对道具应用验证?
52 React 的优势是什么?
53 React 有哪些限制?
54 什么是 React v16 中的错误边界
55 在 React v15 中如何处理错误边界?
56 静态类型检查的推荐方法有哪些?
57 React dom 包有什么用?
58 React 的渲染方法的目的是什么?
59 什么是ReactDOMServer?
60 如何在 React 中使用 InnerHtml?
61 如何在 React 中使用样式?
62 事件在 React 中有何不同?
63 如果在构造函数中使用 setState 会发生什么?
64 索引作为键有什么影响?
65 在 componentWillMount() 方法中使用 setState() 好吗?
66 如果在初始状态下使用道具会发生什么?
67 如何有条件地渲染组件?
68 为什么我们在 DOM 元素上传播道具时需要小心?
69 如何在 React 中使用装饰器?
70 你如何记忆一个组件?
71 如何实现服务器端渲染或 SSR?
72 如何在 React 中启用生产模式?
73 什么是CRA及其好处?
74 装载的生命周期方法顺序是什么?
75 React v16 中将弃用哪些生命周期方法?
76 getDerivedStateFromProps() 生命周期方法的目的是什么?
77 getSnapshotBeforeUpdate() 生命周期方法的目的是什么?
78 钩子会取代渲染道具和高阶组件吗?
79 建议的组件命名方法是什么?
80 组件类中方法的建议顺序是什么?
81 什么是开关元件?
82 为什么我们需要将函数传递给 setState()?
83 什么是 React 中的严格模式?
84 什么是 React Mixins?
85 为什么 Mounted() 是一种反模式,正确的解决方案是什么?
86 React 支持哪些指针事件?
87 为什么组件名称应该以大写字母开头?
88 React v16 是否支持自定义 DOM 属性?
89 构造函数和getInitialState有什么区别?
90 是否可以在不调用 setState 的情况下强制组件重新渲染?
91 使用 ES6 类的 React 中的 super() 和 super(props) 有什么区别?
92 如何在 JSX 内部循环?
93 如何访问属性引号中的道具?
94 什么是带形状的 React PropType 数组?
95 如何有条件地应用类属性?
96 React 和 ReactDOM 有什么区别?
97 为什么 ReactDOM 与 React 分离?
98 如何使用 React 标签元素?
99 如何组合多个内联样式对象?
100 调整浏览器大小时如何重新呈现视图?
101 setState 和 replaceState 方法有什么区别?
102 如何监听状态变化?
103 删除处于 React 状态的数组元素的推荐方法是什么?
104 是否可以在不渲染 HTML 的情况下使用 React?
105 如何使用 React 漂亮地打印 JSON?
106 为什么你不能在 React 中更新道具?
107 如何在页面加载时聚焦输入元素?
108 更新状态中的对象的可能方法有哪些?
110 我们如何在浏览器中找到运行时的 React 版本?
111 在创建- React -应用中包含 polyfill 的方法有哪些?
112 如何在create-react-app中使用https而不是http?
113 如何避免在创建- React -应用中使用相对路径导入?
114 如何为 React 路由器添加谷歌分析?
115 如何每秒更新一个组件?
116 如何将供应商前缀应用于 React 中的内联样式?
117 如何使用 react 和 ES6 导入和导出组件?
118 React 组件命名有哪些例外?
119 为什么组件构造函数只调用一次?
120 如何在 React 中定义常量?
121 如何在 React 中以编程方式触发点击事件?
122 是否可以在普通 React 中使用 async/await?
123 React 的常见文件夹结构是什么?
124 流行的动画包有哪些?
125 样式模块有什么好处?
126 什么是流行的 React 专用短绒?
127 如何进行 AJAX 调用以及应在哪些组件生命周期方法中进行 AJAX 调用?
128 什么是渲染道具?
React 路由器
129 什么是 React Router?
130 React Router 与历史库有何不同?
131 React Router v4 的<路由器>组件是什么?
132 推动和替换历史方法的目的是什么?
133 如何使用 React 路由器 v4 以编程方式导航?
134 如何在 React Router v4 中获取查询参数
135 为什么收到“路由器可能只有一个子元素”警告?
136 如何在 React Router v4 中将参数传递给 history.push 方法?
137 如何实现默认或未找到页面?
138 如何在 React Router v4 上获取历史记录?
139 登录后如何执行自动重定向?
React 国际化
140 什么是 React-Intl?
141 React Intl的主要特点是什么?
142 在 React Intl 中格式化的两种方法是什么?
143 如何使用 React Intl 将 FormattedMessage 用作占位符?
144 如何使用 React Intl 访问当前语言环境
145 如何使用 React 国际机场格式化日期?
React 测试
146 什么是 React 测试中的浅层渲染器?
147 什么是 React 中的 TestRenderer 包?
148 ReactTestUtils软件包的目的是什么?
149 什么是开玩笑?
150 开玩笑与茉莉花相比有什么优势?
151 举一个简单的Jest测试用例的例子
React Redux
152 什么是助焊剂?
153 什么是 Redux?
154 Redux的核心原则是什么?
155 与Flux相比,Redux的缺点是什么?
156 mapStateToProps() 和 mapDispatchToProps() 有什么区别?
157 我可以在化简器中调度操作吗?
158 如何在组件外部访问 Redux 存储?
159 MVW模式的缺点是什么
160 Redux和RxJS之间有什么相似之处吗?
161 如何在加载时调度操作?
162 如何使用来自 React Redux 的连接?
163 如何在Redux中重置状态?
164 在 redux 连接装饰器中 at 符号的目的是什么?
165 React 上下文和 React Redux 有什么区别?
166 为什么 Redux 状态函数被称为化简器?
167 如何在 Redux 中发出 AJAX 请求?
168 我应该将所有组件的状态保留在 Redux 存储中吗?
169 访问 Redux 存储的正确方法是什么?
170 React Redux 中的组件和容器有什么区别?
171 Redux 中常量的目的是什么?
172 编写mapDispatchToProps()有哪些不同的方法?
173 在mapStateToProps()和mapDispatchToProps()中ownProps参数有什么用?
174 如何构建 Redux 顶级目录?
175 什么是 redux-saga?
176 reux-saga的心智模型是什么?
177 在 redux-saga 中调用和放置有什么区别
178 什么是 Redux Thunk?
179 redux-saga和redux-thunk有什么区别
180 什么是 Redux DevTools?
181 Redux DevTools 有哪些功能?
182 什么是 Redux 选择器以及为什么要使用它们?
183 什么是 Redux Form?
184 Redux Form的主要功能是什么?
185 如何在 Redux 中添加多个中间件?
186 如何在 Redux 中设置初始状态?
187 Relay 与 Redux 有何不同?
188 什么是 Redux 中的操作?
React 原生
188 React Native 和 React 有什么区别?
189 如何测试 React Native 应用程序?
190 如何在 React Native 中进行日志记录?
191 如何调试你的 React Native?
React 支持的库和集成
192 什么是重新选择及其工作原理?
193 什么是心流?
194 流和属性类型有什么区别?
195 如何在 React 中使用字体 awesome 图标?
196 什么是 React Dev Tools?
197 为什么 DevTools 没有在 Chrome 中加载本地文件?
198 如何在 React 中使用聚合物?
199 React 相对于 Vue.js 有什么优势?
200 React 和 Angular 有什么区别?
201 为什么 React 选项卡没有显示在 DevTools 中?
202 什么是样式化组件?
203 举一个样式化组件的示例?
204 什么是中继?
205 如何在创建- React -应用程序应用程序中使用打字脚本?
杂项
206 重新选择库的主要功能是什么?
207 举一个重新选择用法的例子?
209 静态对象是否适用于 React 中的 ES6 类?
210 Redux 只能与 React 一起使用吗?
211 你是否需要特定的构建工具来使用 Redux?
212 Redux 表单初始值如何从状态更新?
213 React PropType 如何允许一个道具使用不同的类型?
214 我可以导入 SVG 文件作为 React 组件吗?
215 为什么不建议使用内联引用回调或函数?
216 什么是 React 中的渲染劫持?
217 什么是 HOC 工厂实施?
218 如何将数字传递给 React 组件?
219 我是否需要将所有状态保留到 Redux 中?我应该使用 React 内部状态吗?
220 在 React 中注册服务工作者的目的是什么?
221 什么是 React 备忘录功能?
222 什么是 React 惰性函数?
223 如何使用 setState 防止不必要的更新?
224 如何在 React 16 版本中渲染数组、字符串和数字?
225 如何在 React 类中使用类字段声明语法?
226 什么是钩子?
227 钩子需要遵循哪些规则?
228 如何确保钩子遵循项目中的规则?
229 Flux 和 Redux 有什么区别?
230 React Router V4有什么好处?
231 你能描述一下 componentDidCatch 生命周期方法签名吗?
232 在哪些情况下,错误边界不会捕获错误?
233 为什么事件处理程序不需要错误边界?
234 尝试捕获块和错误边界有什么区别?
235 React 16 中未捕获错误的行为是什么?
236 错误边界的正确位置是什么?
237 从错误边界跟踪组件堆栈有什么好处?
238 为类组件定义所需的方法是什么?
239 渲染方法的可能返回类型有哪些?
240 构造函数的主要目的是什么?
241 是否必须为 React 组件定义构造函数?
242 什么是默认道具?
243 为什么不应该在组件中调用 setStateWillUnmount?
244 getDerivedStateFromError的目的是什么?
245 重新渲染组件时的方法顺序是什么?
246 在错误处理期间调用了哪些方法?
247 显示名称类属性的用途是什么?
248 浏览器对 React 应用程序的支持是什么?
249 unmountComponentAtNode方法的目的是什么?
250 什么是代码拆分?
251 严格模式有什么好处?
252 什么是键控片段?
253 React 是否支持所有 HTML 属性?
254 HOC 有哪些限制?
255 如何在 DevTools 中调试 forwardRefs?
256 当组件道具默认为 true 时?
257 什么是NextJS及其主要功能?
258 如何将事件处理程序传递给组件?
259 在呈现方法中使用箭头函数好吗?
260 如何防止一个函数被多次调用?
261 JSX 如何防止注入攻击?
262 如何更新渲染元素?
263 你怎么说道具是只读的?
264 你怎么说状态更新被合并了?
265 如何将参数传递给事件处理程序?
266 如何防止组件渲染?
267 安全使用索引作为键的条件是什么?
268 密钥是否应该是全局唯一的?
269 表单处理的热门选择是什么?
270 与 redux 表单库相比,formik 的优势是什么?
271 为什么不需要使用继承?
272 我可以在 react 应用程序中使用 Web 组件吗?
273 什么是动态导入?
274 什么是可加载组件?
275 什么是悬念成分?
276 什么是基于路由的代码拆分?
277 举一个关于如何使用上下文的示例?
278 上下文中默认值的目的是什么?
279 你如何使用上下文类型?
280 什么是消费者?
281 如何在使用上下文时解决性能极端情况?
282 HOC 中前向引用的目的是什么?
283 它是否适用于所有函数或类组件的 ref 参数?
284 为什么在使用前向引用时需要额外注意组件库?
285 如何在没有 ES6 的情况下创建 React 类组件?
286 是否可以在没有 JSX 的情况下使用 react ?
287 什么是差异算法?
288 差异算法涵盖哪些规则?
289 什么时候需要使用引用?
290 它是否必须命名为渲染道具的渲染?
291 使用纯组件的渲染道具有什么问题?
292 如何使用渲染道具创建 HOC?
293 什么是窗口技术?
294 如何在 JSX 中打印错误值?
295 门户的典型用例是什么?
296 如何设置不受控制的组件的默认值?
297 你最喜欢的 React 堆栈是什么?
298 Real DOM 和 Virtual DOM 有什么区别?
299 如何将 Bootstrap 添加到 react 应用程序中?
300 你能列出使用 react 作为前端框架的顶级网站或应用程序吗?
301 是否建议在 React 中使用 CSS In JS 技术?
302 我需要用钩子重写我所有的类组件吗?
303 如何使用 React Hooks 获取数据?
304 Hooks 是否涵盖了类的所有用例?
305 钩子支持的稳定版本是什么?
306 为什么我们在useState中使用数组解构(方括号表示法)?
307 引入钩子的来源是什么?
308 如何访问 Web 组件的命令式 API?
309 什么是福米克?
310 在 Redux 中处理异步调用的典型中间件选择是什么?
311 浏览器能理解 JSX 代码吗?
312 描述 React 中的数据流?
313 什么是 React 脚本?
314 创建 React 应用程序有哪些功能?
315 renderToNodeStream 方法的目的是什么?
316 什么是MobX?
317 Redux 和 MobX 有什么区别?
318 我应该在学习 ReactJS 之前学习 ES6 吗?
319 什么是并发渲染?
320 异步模式和并发模式有什么区别?
321 我可以在 react16.9 中使用 javascript url 吗?
322 钩子的 eslint 插件的目的是什么?
323 在 React 中命令式和声明式有什么区别?
324 将打字稿与 reactjs 一起使用有什么好处?
325 在使用上下文 API 状态管理时,如何确保用户在页面刷新时保持身份验证?
326 新的 JSX 转换有哪些好处?
327 新的 JSX 转换与旧转换有何不同?
328 你如何使用创建- React -应用程序获得 redux 脚手架?
329 什么是 React Server 组件?
330 什么是支柱钻孔?
331 什么是状态突变以及如何预防它?
332 useState 和 useRef hook 有什么区别?
333 React 中的函数组件和类组件有什么区别

核心 React

  1. 什么是 React ?

    React 是一个开源的前端 JavaScript 库,用于构建用户界面,尤其是单页应用程序。它用于处理 Web 和移动应用程序的视图层。React是由为Facebook工作的软件工程师Jordan Walke创建的。React于2011年首次部署在Facebook的News Feed上,并于2012年部署在Instagram上。

    返回页首

  2. React 的主要特性是什么?

    React 的主要特性是:

    • 它使用VirtualDOM而不是RealDOM,考虑到RealDOM操作是昂贵的。
    • 支持服务器端渲染
    • 遵循单向数据流或数据绑定。
    • 使用可重用/可组合的 UI 组件来开发视图。

    返回页首

  3. 什么是JSX?

    JSX 是 ECMAScript 的类似 XML 的语法扩展(首字母缩略词代表 JavaScript XML)。基本上,它只是为函数提供语法糖,为我们提供JavaScript的表现力以及类似HTML的模板语法。

    React.createElement()

    在下面的示例中,标记内的文本作为 JavaScript 函数返回给渲染函数。

    <h1>

    class App extends React.Component {
      render() {
        return(
          <div>
            <h1>{'Welcome to React world!'}</h1>
          </div>
        )
      }
    }

    返回页首

  4. 元素和组件有什么区别?

    元素是一个普通对象,描述你希望在屏幕上显示的 DOM 节点或其他组件的内容。元素可以在其道具中包含其他元素。创建一个 React 元素很便宜。一旦创建了元素,它就永远不会发生突变。

    React Element 的对象表示如下:

    const element = React.createElement(
      'div',
      {id: 'login-btn'},
      'Login'
    )

    上面的函数返回一个对象:

    React.createElement()

    {
      type: 'div',
      props: {
        children: 'Login',
        id: 'login-btn'
      }
    }
    

    最后,它通过以下方式渲染到 DOM:

    ReactDOM.render()

    <div id='login-btn'>Login</div>

    组件可以通过几种不同的方式声明。它可以是带有方法的类,也可以定义为函数。无论哪种情况,它都将 props 作为输入,并返回一个 JSX 树作为输出:

    render()

    const Button = ({ onLogin }) =>
      <div id={'login-btn'} onClick={onLogin}>Login</div>

    然后 JSX 被转译为函数树:

    React.createElement()

    const Button = ({ onLogin }) => React.createElement(
      'div',
      { id: 'login-btn', onClick: onLogin },
      'Login'
    )

    返回页首

  5. 如何在 React 中创建组件?

    有两种可能的方法可以创建组件。

    1. 功能组件:这是创建组件的最简单方法。这些是纯 JavaScript 函数,接受 props 对象作为第一个参数并返回 React 元素:

      function Greeting({ message }) {
        return <h1>{`Hello, ${message}`}</h1>
      
      }
    2. 类组件:你还可以使用 ES6 类来定义组件。上面的函数组件可以写成:

      class Greeting extends React.Component {
        render() {
          return <h1>{`Hello, ${this.props.message}`}</h1>
        }
      }

    返回页首

  6. 何时使用类组件而不是函数组件?

    如果组件需要状态或生命周期方法,则使用类组件,否则使用函数组件。但是,从 React 16.8 开始,添加了 Hooks,你可以在函数组件中使用状态、生命周期方法和其他仅在类组件中可用的功能。*因此,始终建议使用函数组件,除非你需要一个 React 功能,其函数组件等效项尚不存在,例如错误边界 *

    返回页首

  7. 什么是纯组件?

    React.PureComponentReact.Component 完全相同,只是它为你处理该方法。当 props 或状态发生变化时,PureComponent 会对 props 和状态进行浅层比较。另一方面,组件不会将当前道具和状态与下一个开箱即用的状态进行比较。因此,默认情况下,每当调用组件时,组件都会重新呈现。

    shouldComponentUpdate()
    shouldComponentUpdate

    返回页首

  8. React 中的状态是什么?

    组件的状态是一个对象,其中包含一些可能在组件生存期内更改的信息。我们应该始终尝试使我们的状态尽可能简单,并尽量减少有状态组件的数量。

    让我们创建一个具有消息状态的用户组件,

    class User extends React.Component {
      constructor(props) {
        super(props)
    
        this.state = {
          message: 'Welcome to React world'
        }
      }
    
      render() {
        return (
          <div>
            <h1>{this.state.message}</h1>
          </div>
        )
      }
    }

    州

    状态类似于 props,但它是私有的并且完全由组件控制,即在所有者组件决定传递它之前,任何其他组件都无法访问它。

    返回页首

  9. React 中的道具是什么?

    道具是组件的输入。它们是单个值或包含一组值的对象,这些值在创建时使用类似于 HTML 标记属性的命名约定传递给组件。它们是从父组件传递到子组件的数据。

    React 中 props 的主要目的是提供以下组件功能:

    1. 将自定义数据传递给组件。
    2. 触发状态更改。
    3. 通过内部组件的方法使用。
      this.props.reactProp
      render()

    例如,让我们创建一个带有属性的元素:

    reactProp

    <Element reactProp={'1'} />

    然后,这个(或任何你想出的)名称成为附加到 React 原生 props 对象的属性,该对象最初已经存在于使用 React 库创建的所有组件上。

    reactProp

    props.reactProp
    

    示例:基于类的组件中的道具

    import React from 'react'
    import ReactDOM from 'react-dom'
    
    class ChildComponent extends React.Component {
        render() {
            return (
                <div>
                    <p>{this.props.name}</p>
                    <p>{this.props.age}</p>
                </div>
            )
        }
    }
    
    class ParentComponent extends React.Component {
        render() {
            return (
                <div>
                    <ChildComponent name='John' age='30' />
                    <ChildComponent name='Mary' age='25' />
                </div>
            )
        }
    }

    示例:功能组件中的道具

    import React from 'react'
    import ReactDOM from 'react-dom'
    
    const ChildComponent = (props) => {
        return (
            <div>
                <p>{props.name}</p>
                <p>{props.age}</p>
            </div>
        )
    }
    
    const ParentComponent = () => {
        return (
            <div>
                <ChildComponent name='John' age='30' />
                <ChildComponent name='Mary' age='25' />
            </div>
        )
    }

    返回页首

  10. 状态和道具有什么区别?

    propsstate 都是普通的 JavaScript 对象。虽然它们都包含影响渲染输出的信息,但它们在组件方面的功能不同。props 类似于函数参数传递给组件,而状态在组件内管理,类似于函数中声明的变量。

返回页首

  1. 为什么我们不应该直接更新状态?

    如果尝试直接更新状态,则不会重新呈现组件。

    //Wrong
    this.state.message = 'Hello world'

    而是使用方法。它计划对组件的状态对象的更新。当状态更改时,组件会通过重新呈现来响应。

    setState()

    //Correct
    this.setState({ message: 'Hello World' })

    注意:你可以在构造函数中或使用最新的 javascript 的类字段声明语法直接分配给状态对象。

返回页首

  1. 回调函数作为参数的目的是什么?
    setState()

    回调函数在 setState 完成并呈现组件时调用。由于是异步的,因此回调函数用于任何发布操作。

    setState()

    注意:建议使用生命周期方法,而不是此回调函数。

    setState({ name: 'John' }, () => console.log('The name has updated and component re-rendered'))

返回页首

  1. HTML 和 React 事件处理有什么区别?

    以下是 HTML 和 React 事件处理之间的一些主要区别,

    1. 在 HTML 中,事件名称通常以小写形式表示为约定:

      <button onclick='activateLasers()'>

      而在 React 中,它遵循 camelCase 约定:

      <button onClick={activateLasers}>
    2. 在 HTML 中,你可以返回以防止默认行为:

      false

      <a href='#' onclick='console.log("The link was clicked."); return false;' />

      而在 React 中,你必须显式调用:

      preventDefault()

      function handleClick(event) {
        event.preventDefault()
        console.log('The link was clicked.')
      }
    3. 在 HTML 中,你需要通过附加 T的方式来调用函数,而在 react 中,你不应该附加函数名称。(例如,请参阅第一点中的“激活激光”功能)

      ()
      ()

返回页首

  1. 如何在 JSX 回调中绑定方法或事件处理程序?

    有 3 种可能的方法可以实现此目的:

    1. 构造函数中的绑定:在 JavaScript 类中,默认情况下不绑定这些方法。同样的事情也适用于定义为类方法的 React 事件处理程序。通常我们在构造函数中绑定它们。

      class Foo extends Component {
        constructor(props) {
          super(props);
          this.handleClick = this.handleClick.bind(this);
        }
        handleClick() {
          console.log('Click happened');
        }
        render() {
          return <button onClick={this.handleClick}>Click Me</button>;
        }
      }
    2. 公共类字段语法:如果你不喜欢使用绑定方法,则可以使用公共类字段语法来正确绑定回调。

      handleClick = () => {
        console.log('this is:', this)
      }
      <button onClick={this.handleClick}>
        {'Click me'}
      </button>
    3. 回调中的箭头函数:可以直接在回调中使用箭头函数

      handleClick() {
          console.log('Click happened');
      }
      render() {
          return <button onClick={() => this.handleClick()}>Click Me</button>;
      }

    注意:如果回调作为 prop 传递给子组件,则这些组件可能会执行额外的重新渲染。在这些情况下,最好使用考虑性能的公共类字段语法方法。

    .bind()

返回页首

  1. 如何将参数传递给事件处理程序或回调?

    可以使用箭头函数环绕事件处理程序并传递参数:

    <button onClick={() => this.handleClick(id)} />

    这等效于调用:

    .bind

    <button onClick={this.handleClick.bind(this, id)} />

    除了这两种方法之外,你还可以将参数传递给定义为箭头函数的函数

    <button onClick={this.handleClick(id)} />
    handleClick = (id) => () => {
        console.log("Hello, your ticket number is", id)
    };

返回页首

  1. 什么是 React 中的合成事件?

    SyntheticEvent
    是围绕浏览器本机事件的跨浏览器包装器。它的 API 与浏览器的本机事件相同,包括 和 ,只是这些事件在所有浏览器中的工作方式相同。
    stopPropagation()
    preventDefault()

返回页首

  1. 什么是内联条件表达式?

    你可以使用 if 语句或 JS 中可用的三元表达式来有条件地呈现表达式。除了这些方法之外,你还可以在 JSX 中嵌入任何表达式,方法是将它们括在大括号中,然后是 JS 逻辑运算符。

    &&

    <h1>Hello!</h1>
    {
        messages.length > 0 && !isLogin?
          <h2>
              You have {messages.length} unread messages.
          </h2>
          :
          <h2>
              You don't have unread messages.
          </h2>
    }

返回页首

  1. 什么是“键”道具,在元素数组中使用它有什么好处?

    A 是创建元素数组时包含的特殊字符串属性。道具帮助 React 识别哪些项目已更改、添加或删除。

    key

    大多数情况下,我们使用数据中的 ID 作为

    const todoItems = todos.map((todo) =>
      <li key={todo.id}>
        {todo.text}
      </li>
    )

    当你没有渲染项的稳定 ID 时,可以使用项索引作为键作为最后的手段:

    const todoItems = todos.map((todo, index) =>
      <li key={index}>
        {todo.text}
      </li>
    )

    注意:

    1. 如果项的顺序可能会更改,则不建议使用索引。这可能会对性能产生负面影响,并可能导致组件状态问题。
    2. 如果将列表项提取为单独的组件,则在列表组件而不是标记上应用
      li
    3. 如果 prop 未出现在列表项上,控制台中将出现警告消息。
      key

返回页首

  1. 引用有什么用?

    引用用于返回对元素的引用。在大多数情况下,应避免使用它们,但是,当你需要直接访问 DOM 元素或组件实例时,它们可能很有用。

返回页首

  1. 如何创建引用?

    有两种方法

    1. 这是最近添加的方法。引用是使用方法创建的,并通过属性附加到 React 元素。为了在整个组件中使用 ref只需将 ref 分配给构造函数中的实例属性。

      React.createRef()
      ref

      class MyComponent extends React.Component {
        constructor(props) {
          super(props)
          this.myRef = React.createRef()
        }
        render() {
          return <div ref={this.myRef} />
        }
      }
    2. 你也可以使用 ref 回调方法,而不管 React 版本如何。例如,按如下方式访问搜索栏组件的输入元素,

      class SearchBar extends Component {
         constructor(props) {
            super(props);
            this.txtSearch = null;
            this.state = { term: '' };
            this.setInputSearchRef = e => {
               this.txtSearch = e;
            }
         }
         onInputChange(event) {
            this.setState({ term: this.txtSearch.value });
         }
         render() {
            return (
               <input
                  value={this.state.term}
                  onChange={this.onInputChange.bind(this)}
                  ref={this.setInputSearchRef} />
            );
         }
      }

    你还可以使用闭包在函数组件中使用 refs注意:你也可以使用内联引用回调,即使这不是推荐的方法。

返回页首

  1. 什么是前向引用?

    引用转发是一项功能,它允许某些组件获取它们收到的引用,并将其进一步传递给子项。

    const ButtonElement = React.forwardRef((props, ref) => (
      <button ref={ref} className="CustomButton">
        {props.children}
      </button>
    ));
    
    // Create ref to the DOM button:
    const ref = React.createRef();
    <ButtonElement ref={ref}>{'Forward Ref'}</ButtonElement>

返回页首

  1. 回调引用和 findDOMNode() 哪个是首选选项?

    最好使用回调引用而不是 API。因为会阻止将来 React 中的某些改进。

    findDOMNode()
    findDOMNode()

    使用的传统方法:

    findDOMNode

    class MyComponent extends Component {
      componentDidMount() {
        findDOMNode(this).scrollIntoView()
      }
    
      render() {
        return <div />
      }
    }

    推荐的方法是:

    class MyComponent extends Component {
      constructor(props){
        super(props);
        this.node = createRef();
      }
      componentDidMount() {
        this.node.current.scrollIntoView();
      }
    
      render() {
        return <div ref={this.node} />
      }
    }

返回页首

  1. 为什么字符串引用是遗留的?

    如果你以前使用过 React,你可能熟悉较旧的 API,其中属性是字符串,例如 ,并且 DOM 节点以 .我们建议不要这样做,因为字符串引用有以下问题,并且被认为是遗留的。字符串引用在 React v16 中删除

    ref
    ref={'textInput'}
    this.refs.textInput

    1. 它们迫使 React 跟踪当前正在执行的组件。这是有问题的,因为它使 React 模块有状态,因此当 React 模块在捆绑包中复制时会导致奇怪的错误。
    2. 它们是不可组合的——如果一个库在传递的子子项上放了一个引用,用户就不能在上面放另一个引用。回调引用是完全可组合的。
    3. 它们不适用于 Flow 等静态分析。Flow 无法猜测框架使字符串 ref 出现在 上的魔力,以及它的类型(可能不同)。回调引用对静态分析更友好。
      this.refs
    4. 它不像大多数人期望的那样使用“渲染回调”模式(例如)
      class MyComponent extends Component {
        renderRow = (index) => {
          // This won't work. Ref will get attached to DataTable rather than MyComponent:
          return <input ref={'input-' + index} />;
      
          // This would work though! Callback refs are awesome.
          return <input ref={input => this['input-' + index] = input} />;
        }
      
        render() {
          return <DataTable data={this.props.data} renderRow={this.renderRow} />
        }
      }

返回页首

  1. 什么是虚拟 DOM?

    虚拟 DOM (VDOM) 是真实 DOM 的内存表示形式。UI 的表示形式保存在内存中,并与“真正的”DOM 同步。这是在调用的渲染函数和在屏幕上显示元素之间发生的步骤。整个过程称为和解

返回页首

  1. 虚拟 DOM 如何工作?

    虚拟 DOM 通过三个简单的步骤工作。

    1. 每当任何基础数据发生更改时,整个 UI 都会以虚拟 DOM 表示形式重新呈现。

      vdom

    2. 然后计算以前的 DOM 表示和新的 DOM 表示之间的差异。

      vdom2

    3. 计算完成后,真正的 DOM 将只更新实际更改的内容。

      vdom3

返回页首

  1. Shadow DOM和Virtual DOM有什么区别?

    Shadow DOM 是一种浏览器技术,主要用于在 Web 组件中限定变量和 CSS 的作用域。虚拟 DOM 是由 JavaScript 中的库在浏览器 API 之上实现的概念。

返回页首

  1. 什么是 React Fiber?

    Fiber 是 React v16 中核心算法的新协调引擎或重新实现。React Fiber 的目标是提高其对动画、布局、手势、暂停、中止或重用工作的能力以及为不同类型的更新分配优先级等领域的适用性;和新的并发原语。

返回页首

  1. React Fiber 的主要目标是什么?

    React Fiber 的目标是提高其对动画、布局和手势等领域的适用性。它的主要功能是增量渲染:能够将渲染工作拆分为块并将其分布在多个帧上。

    从文档

    其主要目标是:

    1. 能够将可中断的工作分成块。
    2. 能够确定正在进行的工作的优先级、变基和重用。
    3. 能够在父母和孩子之间来回屈服以支持 React 中的布局。
    4. 能够从 render() 返回多个元素。
    5. 更好地支持错误边界。

返回页首

  1. 什么是受控组件?

    在后续用户输入中控制表单中的输入元素的组件称为受控组件,即每个状态突变都将具有关联的处理程序函数。

    例如,要用大写字母写所有名称,我们使用handleChange,如下所示,

    handleChange(event) {
      this.setState({value: event.target.value.toUpperCase()})
    }

返回页首

  1. 什么是不受控制的组件?

    不受控制的组件是在内部存储自己的状态的组件,你可以使用 ref 查询 DOM 以在需要时查找其当前值。这有点像传统的HTML。

    在下面的用户配置文件组件中,使用 ref 访问输入。

    name

    class UserProfile extends React.Component {
      constructor(props) {
        super(props)
        this.handleSubmit = this.handleSubmit.bind(this)
        this.input = React.createRef()
      }
    
      handleSubmit(event) {
        alert('A name was submitted: ' + this.input.current.value)
        event.preventDefault()
      }
    
      render() {
        return (
          <form onSubmit={this.handleSubmit}>
            <label>
              {'Name:'}
              <input type="text" ref={this.input} />
            </label>
            <input type="submit" value="Submit" />
          </form>
        );
      }
    }

    在大多数情况下,建议使用受控组件来实现表单。在受控组件中,表单数据由 React 组件处理。另一种方法是不受控制的组件,其中表单数据由 DOM 本身处理。

返回页首

  1. createElement 和 cloneElement 有什么区别?

    JSX 元素将被转译为函数以创建将用于 UI 对象表示的 React 元素。而 用于克隆元素并向其传递新道具。

    React.createElement()
    cloneElement

返回页首

  1. 什么是在 React 中提升状态?

    当多个组件需要共享相同的更改数据时,建议将共享状态提升到其最接近的共同祖先。这意味着,如果两个子组件共享其父组件的相同数据,则将状态移动到父组件,而不是在两个子组件中维护本地状态。

返回页首

  1. 组件生命周期有哪些不同阶段?

    组件生命周期有三个不同的生命周期阶段:

    1. 安装:组件已准备好挂载到浏览器 DOM 中。此阶段涵盖从 、 、 和生命周期方法初始化。

      constructor()
      getDerivedStateFromProps()
      render()
      componentDidMount()

    2. 更新:在此阶段,组件以两种方式更新,发送新 props 并从 或 更新状态。此阶段涵盖 、 和生命周期方法。

      setState()
      forceUpdate()
      getDerivedStateFromProps()
      shouldComponentUpdate()
      render()
      getSnapshotBeforeUpdate()
      componentDidUpdate()

    3. 卸载:在最后一个阶段,不需要该组件,并从浏览器 DOM 中卸载。此阶段包括生命周期方法。

      componentWillUnmount()

    值得一提的是,React 内部在对 DOM 应用更改时有一个阶段的概念。它们分开如下

    1. 呈现该组件将呈现没有任何副作用。这适用于 Pure 组件,在此阶段,React 可以暂停、中止或重新启动渲染。

    2. 预提交在组件实际将更改应用于 DOM 之前,有一个时刻允许 React 通过 .

      getSnapshotBeforeUpdate()

    3. React 与 DOM 一起工作,并分别执行挂载、更新和卸载的最终生命周期。

      componentDidMount()
      componentDidUpdate()
      componentWillUnmount()

    React 16.3+ Phases(或交互式版本)

    阶段 16.4+

    在 React 16.3 之前

    阶段 16.2

返回页首

  1. React 的生命周期方法是什么?

    在 React 16.3 之前

    • 组件将挂载:在呈现之前执行,用于根组件中的应用级别配置。
    • 组件DidMount:在首次渲染后执行,此处应发生所有 AJAX 请求、DOM 或状态更新以及设置事件侦听器。
    • componentWillReceiveProps:当特定道具更新以触发状态转换时执行。
    • 应该组件更新:确定是否更新组件。默认情况下,它返回 .如果你确定组件在更新状态或 props 后不需要渲染,则可以返回 false 值。这是提高性能的好地方,因为它允许你在组件收到新 prop 时防止重新渲染。
      true
    • 组件将更新:在重新渲染组件之前执行,当确认有 props 和状态更改时返回 true。
      shouldComponentUpdate()
    • 组件更新:大多数情况下,它用于更新 DOM 以响应 prop 或状态更改。
    • 组件将卸载:它将用于取消任何传出网络请求,或删除与组件关联的所有事件侦听器。

    React 16.3+

    • getDerivedStateFromProps:在调用之前调用,并在每次渲染时调用。这适用于需要派生状态的罕见用例。如果你需要派生状态,值得一读。
      render()
    • 组件DidMount:在首次呈现后执行,所有 AJAX 请求、DOM 或状态更新以及设置事件侦听器都应发生。
    • 应该组件更新:确定是否更新组件。默认情况下,它返回 .如果你确定组件在更新状态或 props 后不需要渲染,则可以返回 false 值。这是提高性能的好地方,因为它允许你在组件收到新道具时防止重新渲染。
      true
    • getSnapshotBeforeUpdate:在渲染输出提交到 DOM 之前执行。由此返回的任何值都将传递到 .这对于从 DOM 捕获信息(即滚动位置)很有用。
      componentDidUpdate()
    • 组件更新:大多数情况下,它用于更新 DOM 以响应 prop 或状态更改。如果返回,这不会触发。
      shouldComponentUpdate()
      false
    • 组件将卸载它将用于取消任何传出网络请求,或删除与组件关联的所有事件侦听器。

返回页首

  1. 什么是高阶组件?

    高阶组件HOC) 是获取组件并返回新组件的函数。基本上,这是一种源自 React 的合成性质的模式。

    我们称它们为纯组件,因为它们可以接受任何动态提供的子组件,但它们不会修改或复制其输入组件中的任何行为。

    const EnhancedComponent = higherOrderComponent(WrappedComponent)

    HOC 可用于许多用例:

    1. 代码重用、逻辑和引导抽象。
    2. 渲染劫持。
    3. 状态抽象和操作。
    4. 道具操纵。

返回页首

  1. 如何为 HOC 组件创建道具代理?

    你可以使用 props 代理模式添加/编辑传递给组件的 props,如下所示:

    function HOC(WrappedComponent) {
      return class Test extends Component {
        render() {
          const newProps = {
            title: 'New Header',
            footer: false,
            showFeatureX: false,
            showFeatureY: true
          }
    
          return <WrappedComponent {...this.props} {...newProps} />
        }
      }
    }

返回页首

  1. 什么是上下文?

    上下文提供了一种通过组件树传递数据的方法,而不必在每个级别手动传递 props。

    例如,经过身份验证的用户、区域设置首选项、UI 主题需要由许多组件在应用程序中访问。

    const {Provider, Consumer} = React.createContext(defaultValue)

返回页首

  1. 什么是儿童道具?

    Children 是一个 prop (),它允许你将组件作为数据传递给其他组件,就像你使用的任何其他 prop 一样。放在组件的开始和结束标记之间的组件树将作为 prop 传递给该组件。

    this.props.children
    children

    React API 中有几种方法可以使用这个 prop。其中包括 、 、 、 。

    React.Children.map
    React.Children.forEach
    React.Children.count
    React.Children.only
    React.Children.toArray

    儿童道具的简单用法如下所示,

    const MyDiv = React.createClass({
      render: function() {
        return <div>{this.props.children}</div>
      }
    })
    
    ReactDOM.render(
      <MyDiv>
        <span>{'Hello'}</span>
        <span>{'World'}</span>
      </MyDiv>,
      node
    )

返回页首

  1. 如何在 React 中写评论?

    React/JSX 中的注释类似于 JavaScript 多行注释,但用大括号括起来。

    单行注释:

    <div>
      {/* Single-line comments(In vanilla JavaScript, the single-line comments are represented by double slash(//)) */}
      {`Welcome ${user}, let's play React`}
    </div>

    多行注释:

    <div>
      {/* Multi-line comments for more than
       one line */}
      {`Welcome ${user}, let's play React`}
    </div>

返回页首

  1. 使用带有道具参数的超级构造函数的目的是什么?

    在调用该方法之前,子类构造函数无法使用引用。这同样适用于 ES6 子类。将 props 参数传递给调用的主要原因是访问子构造函数。

    this
    super()
    super()
    this.props

    传球道具:

    class MyComponent extends React.Component {
      constructor(props) {
        super(props)
    
        console.log(this.props) // prints { name: 'John', age: 42 }
      }
    }

    不传递道具:

    class MyComponent extends React.Component {
      constructor(props) {
        super()
    
        console.log(this.props) // prints undefined
    
        // but props parameter is still available
        console.log(props) // prints { name: 'John', age: 42 }
      }
    
      render() {
        // no difference outside constructor
        console.log(this.props) // prints { name: 'John', age: 42 }
      }
    }

    上面的代码片段揭示了仅在构造函数中有所不同。在构造函数外部也是如此。

    this.props

返回页首

  1. 什么是和解?

    当组件的 props 或状态发生变化时,React 通过将新返回的元素与之前渲染的元素进行比较来决定是否需要实际的 DOM 更新。当它们不相等时,React 将更新 DOM。此过程称为协调

返回页首

  1. 如何使用动态键名称设置状态?

    如果你使用 ES6 或 Babel 转译器来转换 JSX 代码,则可以使用计算的属性名称来完成此操作。

    handleInputChange(event) {
      this.setState({ [event.target.id]: event.target.value })
    }

返回页首

  1. 每次组件渲染时调用函数的常见错误是什么?

    你需要确保在将函数作为参数传递时未调用该函数。

    render() {
      // Wrong: handleClick is called instead of passed as a reference!
      return <button onClick={this.handleClick()}>{'Click Me'}</button>
    }

    相反,传递函数本身而不带括号:

    render() {
      // Correct: handleClick is passed as a reference!
      return <button onClick={this.handleClick}>{'Click Me'}</button>
    }

返回页首

  1. 惰性函数是否支持命名导出?

    否,当前函数仅支持默认导出。如果要导入名为 exports 的模块,可以创建一个中间模块,将其重新导出为默认值。它还确保树摇晃继续工作,并且不会拉动未使用的组件。让我们以导出多个命名组件的组件文件为例,
    React.lazy
    // MoreComponents.js
    export const SomeComponent = /* ... */;
    export const UnusedComponent = /* ... */;
    并在中间文件中重新导出组件
    MoreComponents.js
    IntermediateComponent.js
    // IntermediateComponent.js
    export { SomeComponent as default } from "./MoreComponents.js";
    现在你可以使用惰性函数导入模块,如下所示,
    import React, { lazy } from 'react';
    const SomeComponent = lazy(() => import("./IntermediateComponent.js"));

返回页首

  1. 为什么 React 使用 over 属性?
    className
    class

    class
    是 JavaScript 中的一个关键字,JSX 是 JavaScript 的扩展。这就是 React 使用而不是 .传递一个字符串作为道具。
    className
    class
    className

    render() {
      return <span className={'menu navigation-menu'}>{'Menu'}</span>
    }

返回页首

  1. 什么是片段?

    这是 React 中的一种常见模式,用于组件返回多个元素。片段允许你对子节点列表进行分组,而无需向 DOM 添加额外的节点。

    render() {
      return (
        <React.Fragment>
          <ChildA />
          <ChildB />
          <ChildC />
        </React.Fragment>
      )
    }

    还有一个较短的语法,但许多工具不支持它:

    render() {
      return (
        <>
          <ChildA />
          <ChildB />
          <ChildC />
        </>
      )
    }

返回页首

  1. 为什么片段比容器 div 更好?

    以下是原因列表,

    1. 片段速度更快一些,并且通过不创建额外的 DOM 节点而使用更少的内存。这只对非常大和深的树木有真正的好处。
    2. 一些 CSS 机制(如 FlexboxCSS Grid)具有特殊的父子关系,在中间添加 div 使得很难保持所需的布局。
    3. DOM 检查器不那么混乱。

返回页首

  1. 什么是 React 中的门户?

    门户是将子节点呈现到父组件的 DOM 层次结构之外的 DOM 节点的推荐方法。

    ReactDOM.createPortal(child, container)

    第一个参数是任何可渲染的 React 子参数,例如元素、字符串或片段。第二个参数是 DOM 元素。

返回页首

  1. 什么是无状态组件?

    如果组件的行为与其状态无关,那么它可以是无状态组件。可以使用函数或类来创建无状态组件。但是,除非你需要在组件中使用生命周期钩子,否则你应该选择函数组件。如果你决定在这里使用函数组件,有很多好处;它们易于编写、理解和测试,速度更快,你可以完全避免使用关键字。

    this

返回页首

  1. 什么是有状态组件?

    如果组件的行为依赖于组件的状态,则可以将其称为有状态组件。这些有状态组件始终是类组件,并且具有在 中初始化的状态。

    constructor

    class App extends Component {
      constructor(props) {
        super(props)
        this.state = { count: 0 }
      }
    
      render() {
        // ...
      }
    }

    React 16.8 更新:

    钩子允许你使用状态和其他 React 功能,而无需编写类。

    等效功能组件

     import React, {useState} from 'react';
    
     const App = (props) => {
       const [count, setCount] = useState(0);
    
       return (
         // JSX
       )
     }

返回页首

  1. 如何在 React 中对道具应用验证?

    当应用程序在开发模式下运行时,React 会自动检查我们在组件上设置的所有 props,以确保它们具有正确的类型。如果类型不正确,React 将在控制台中生成警告消息。由于性能影响,它在生产模式下被禁用。强制道具由 定义。

    isRequired

    预定义道具类型的集合:

    1. PropTypes.number
    2. PropTypes.string
    3. PropTypes.array
    4. PropTypes.object
    5. PropTypes.func
    6. PropTypes.node
    7. PropTypes.element
    8. PropTypes.bool
    9. PropTypes.symbol
    10. PropTypes.any

    我们可以为组件定义如下:

    propTypes
    User

    import React from 'react'
    import PropTypes from 'prop-types'
    
    class User extends React.Component {
      static propTypes = {
        name: PropTypes.string.isRequired,
        age: PropTypes.number.isRequired
      }
    
      render() {
        return (
          <>
            <h1>{`Welcome, ${this.props.name}`}</h1>
            <h2>{`Age, ${this.props.age}`}</h2>
          </>
        )
      }
    }

    注意:在 React v15.5 中,PropType 被移到了库中。

    React.PropTypes
    prop-types

    等效功能组件

    import React from 'react'
    import PropTypes from 'prop-types'
    
    function User({name, age}) {
      return (
        <>
          <h1>{`Welcome, ${name}`}</h1>
          <h2>{`Age, ${age}`}</h2>
        </>
      )
    }
    
    User.propTypes = {
        name: PropTypes.string.isRequired,
        age: PropTypes.number.isRequired
      }

返回页首

  1. React 的优势是什么?

    以下是 React 的主要优点列表,

    1. 使用虚拟 DOM 提高应用程序的性能。
    2. JSX 使代码易于读取和编写。
    3. 它在客户端和服务器端 (SSR) 上呈现。
    4. 易于与框架(Angular,Backbone)集成,因为它只是一个视图库。
    5. 使用Jest等工具轻松编写单元和集成测试。

返回页首

  1. React 有哪些限制?

    除了优点之外,React 也几乎没有限制,

    1. React 只是一个视图库,而不是一个完整的框架。
    2. 对于不熟悉 Web 开发的初学者来说,有一个学习曲线。
    3. 将 React 集成到传统的 MVC 框架中需要一些额外的配置。
    4. 代码复杂性随着内联模板和 JSX 的增加而增加。
    5. 太多较小的组件导致过度工程或样板。

返回页首

  1. React v16 中的错误边界是什么?

    错误边界是在其子组件树中的任何位置捕获 JavaScript 错误的组件,记录这些错误,并显示回退 UI,而不是崩溃的组件树。

    如果类组件定义了一个名为 或 的新生命周期方法,则类组件将成为错误边界:

    componentDidCatch(error, info)
    static getDerivedStateFromError() 

    class ErrorBoundary extends React.Component {
      constructor(props) {
        super(props)
        this.state = { hasError: false }
      }
    
      componentDidCatch(error, info) {
        // You can also log the error to an error reporting service
        logErrorToMyService(error, info)
      }
    
      static getDerivedStateFromError(error) {
         // Update state so the next render will show the fallback UI.
         return { hasError: true };
       }
    
      render() {
        if (this.state.hasError) {
          // You can render any custom fallback UI
          return <h1>{'Something went wrong.'}</h1>
        }
        return this.props.children
      }
    }

    之后将其用作常规组件:

    <ErrorBoundary>
      <MyWidget />
    </ErrorBoundary>

返回页首

  1. 在 React v15 中如何处理错误边界?

    React v15 使用方法为错误边界提供了非常基本的支持。它已在 React v16 中重命名。

    unstable_handleError
    componentDidCatch

返回页首

  1. 静态类型检查的推荐方法有哪些?

    通常我们使用 PropType 库(自 React v15.5 以来移至包)在 React 应用程序中进行类型检查。对于大型代码库,建议使用静态类型检查器(如 Flow 或 TypeScript),它们在编译时执行类型检查并提供自动完成功能。

    React.PropTypes
    prop-types

返回页首

  1. 包装有什么用?
    react-dom

    该包提供了特定于 DOM 的方法,可在应用的顶层使用。大多数组件不需要使用此模块。此包的一些方法是:

    react-dom

    1. render()
    2. hydrate()
    3. unmountComponentAtNode()
    4. findDOMNode()
    5. createPortal()

返回页首

  1. 渲染方法的目的是什么?
    react-dom

    此方法用于将 React 元素呈现到提供的容器中的 DOM 中,并返回对该组件的引用。如果 React 元素之前被渲染到容器中,它将对其执行更新,并且仅在必要时改变 DOM 以反映最新的更改。

    ReactDOM.render(element, container, [callback])
    

    如果提供了可选回调,它将在组件渲染或更新后执行。

返回页首

  1. 什么是ReactDOMServer?

    该对象使你能够将组件呈现为静态标记(通常在节点服务器上使用)。此对象主要用于服务器端渲染 (SSR)。以下方法可以在服务器和浏览器环境中使用:

    ReactDOMServer

    1. renderToString()
    2. renderToStaticMarkup()

    例如,你通常运行基于 Node 的 Web 服务器,如 Express、happy 或 Koa,然后调用以将根组件呈现为字符串,然后将其作为响应发送。

    renderToString

    // using Express
    import { renderToString } from 'react-dom/server'
    import MyPage from './MyPage'
    
    app.get('/', (req, res) => {
      res.write('<!DOCTYPE html><html><head><title>My Page</title></head><body>')
      res.write('<div id="content">')
      res.write(renderToString(<MyPage/>))
      res.write('</div></body></html>')
      res.end()
    })

返回页首

  1. 如何在 React 中使用 innerHTML?

    该属性是 React 在浏览器 DOM 中使用的替代品。就像 一样,考虑到跨站点脚本 (XSS) 攻击,使用此属性是有风险的。你只需要将对象作为键传递,将 HTML 文本作为值传递。

    dangerouslySetInnerHTML
    innerHTML
    innerHTML
    __html

    在此示例中,MyComponent 使用属性来设置 HTML 标记:

    dangerouslySetInnerHTML

    function createMarkup() {
      return { __html: 'First &middot; Second' }
    }
    
    function MyComponent() {
      return <div dangerouslySetInnerHTML={createMarkup()} />
    }

返回页首

  1. 如何在 React 中使用样式?

    该属性接受具有驼峰属性的 JavaScript 对象,而不是 CSS 字符串。这与 DOM 风格的 JavaScript 属性一致,效率更高,并防止 XSS 安全漏洞。

    style

    const divStyle = {
      color: 'blue',
      backgroundImage: 'url(' + imgUrl + ')'
    };
    
    function HelloWorldComponent() {
      return <div style={divStyle}>Hello World!</div>
    }

    样式键是驼峰化的,以便与访问 JavaScript 中 DOM 节点上的属性保持一致(例如)。

    node.style.backgroundImage

返回页首

  1. 事件在 React 中有何不同?

    在 React 元素中处理事件有一些语法差异:

    1. React 事件处理程序使用 camelCase 而不是小写来命名。
    2. 使用 JSX,你可以传递函数作为事件处理程序,而不是字符串。

返回页首

  1. 如果在构造函数中使用会发生什么?
    setState()

    当你使用 时,除了分配给对象状态之外,React 还会重新渲染组件及其所有子组件。你会收到如下错误:只能更新已装载或已装载的组件。所以我们需要使用 在构造函数中初始化变量。

    setState()
    this.state

返回页首

  1. 索引作为键有什么影响?

    键应该是稳定的、可预测的和唯一的,以便 React 可以跟踪元素。

    在下面的代码片段中,每个元素的键将基于排序,而不是绑定到所表示的数据。这限制了 React 可以做的优化。

    {todos.map((todo, index) =>
      <Todo
        {...todo}
        key={index}
      />
    )}

    如果你使用元素数据作为唯一键,假设 todo.id 对于这个列表是唯一的并且稳定,React 将能够重新排序元素,而无需重新评估它们。

    {todos.map((todo) =>
      <Todo {...todo}
        key={todo.id} />
    )}

返回页首

  1. 在方法中使用好吗?
    setState()
    componentWillMount()

    是的,在内部使用方法是安全的。但同时建议避免生命周期方法中的异步初始化。 在装载发生之前立即调用。它在 之前调用,因此在此方法中设置状态不会触发重新渲染。避免在此方法中引入任何副作用或订阅。我们需要确保在 中而不是 中发生组件初始化的异步调用。

    setState()
    componentWillMount()
    componentWillMount()
    componentWillMount()
    render()
    componentDidMount()
    componentWillMount()

    componentDidMount() {
      axios.get(`api/todos`)
        .then((result) => {
          this.setState({
            messages: [...result.data]
          })
        })
    }

返回页首

  1. 如果在初始状态下使用道具会发生什么?

    如果在未刷新组件的情况下更改组件上的 props,则永远不会显示新的 prop 值,因为构造函数永远不会更新组件的当前状态。来自 props 的状态初始化仅在首次创建组件时运行。

    以下组件不会显示更新的输入值:

    class MyComponent extends React.Component {
      constructor(props) {
        super(props)
    
        this.state = {
          records: [],
          inputValue: this.props.inputValue
        };
      }
    
      render() {
        return <div>{this.state.inputValue}</div>
      }
    }

    在渲染方法中使用 props 将更新值:

    class MyComponent extends React.Component {
      constructor(props) {
        super(props)
    
        this.state = {
          record: []
        }
      }
    
      render() {
        return <div>{this.props.inputValue}</div>
      }
    }

返回页首

  1. 如何有条件地渲染组件?

    在某些情况下,你希望根据某些状态呈现不同的组件。JSX 不呈现 或 ,因此仅当特定条件为真时,才可以使用条件短路来呈现组件的给定部分。

    false
    undefined

    const MyComponent = ({ name, address }) => (
      <div>
        <h2>{name}</h2>
        {address &&
          <p>{address}</p>
        }
      </div>
    )

    如果需要条件,请使用三元运算符

    if-else

    const MyComponent = ({ name, address }) => (
      <div>
        <h2>{name}</h2>
        {address
          ? <p>{address}</p>
          : <p>{'Address is not available'}</p>
        }
      </div>
    )

返回页首

  1. 为什么我们在 DOM 元素上传播道具时需要小心?

    当我们传播道具时,我们会遇到添加未知HTML属性的风险,这是一种不好的做法。相反,我们可以将 prop 解构与运算符一起使用,因此它将只添加所需的 prop。

    ...rest

    例如

    const ComponentA = () =>
      <ComponentB isDisplay={true} className={'componentStyle'} />
    
    const ComponentB = ({ isDisplay, ...domProps }) =>
      <div {...domProps}>{'ComponentB'}</div>

返回页首

  1. 如何在 React 中使用装饰器?

    你可以修饰组件,这与将组件传递到函数中相同。装饰器是修改组件功能的灵活且可读的方式。

    @setTitle('Profile')
    class Profile extends React.Component {
        //....
    }
    
    /*
      title is a string that will be set as a document title
      WrappedComponent is what our decorator will receive when
      put directly above a component class as seen in the example above
    */
    const setTitle = (title) => (WrappedComponent) => {
      return class extends React.Component {
        componentDidMount() {
          document.title = title
        }
    
        render() {
          return <WrappedComponent {...this.props} />
        }
      }
    }

    注意:装饰器是一个没有进入ES7的功能,但目前是第二阶段的提案

返回页首

  1. 你如何记忆一个组件?

    有可用于函数组件的记忆库。

    例如,库可以记忆另一个组件中的组件。

    moize

    import moize from 'moize'
    import Component from './components/Component' // this module exports a non-memoized component
    
    const MemoizedFoo = moize.react(Component)
    
    const Consumer = () => {
      <div>
        {'I will memoize the following entry:'}
        <MemoizedFoo/>
      </div>
    }

    更新:从 React v16.6.0 开始,我们有一个 .它提供了一个高阶组件,除非道具发生变化,否则它会记住组件。要使用它,只需在使用它之前使用 React.memo 包装组件。

    React.memo

      const MemoComponent = React.memo(function MemoComponent(props) {
        /* render using props */
      });
      OR
      export default React.memo(MyFunctionComponent);

返回页首

  1. 如何实现服务器端渲染或 SSR?

    React 已经具备了处理 Node 服务器上渲染的能力。可以使用特殊版本的 DOM 渲染器,它遵循与客户端相同的模式。

    import ReactDOMServer from 'react-dom/server'
    import App from './App'
    
    ReactDOMServer.renderToString(<App />)

    此方法会将常规 HTML 输出为字符串,然后可以将其作为服务器响应的一部分放置在页面正文中。在客户端,React 会检测预渲染的内容,并无缝地从中断的地方继续。

返回页首

  1. 如何在 React 中启用生产模式?

    你应该使用 Webpack 的方法设置为 ,通过这种方法,它会去除诸如 propType 验证和额外警告之类的内容。除此之外,如果你缩小代码,例如,Uglify的死代码消除以去除仅开发代码和注释,它将大大减少捆绑包的大小。

    DefinePlugin
    NODE_ENV
    production

返回页首

  1. 什么是CRA及其好处?

    CLI 工具允许你快速创建和运行 React 应用程序,而无需配置步骤。

    create-react-app

    让我们使用 CRA 创建待办事项应用程序:

    # Installation
    $ npm install -g create-react-app
    
    # Create new project
    $ create-react-app todo-app
    $ cd todo-app
    
    # Build, test and run
    $ npm run build
    $ npm run test
    $ npm start

    它包含了我们构建 React 应用程序所需的一切:

    1. React、JSX、ES6 和 Flow 语法支持。
    2. ES6 之外的其他语言,如对象传播运算符。
    3. 自动前缀 CSS,因此你不需要 -webkit- 或其他前缀。
    4. 一个快速的交互式单元测试运行程序,内置了对覆盖率报告的支持。
    5. 一个实时开发服务器,警告常见错误。
    6. 一个构建脚本,用于捆绑 JS、CSS 和用于生产的映像,以及哈希和源映射。

返回页首

  1. 装载的生命周期方法顺序是什么?

    创建组件实例并将其插入到 DOM 中时,将按以下顺序调用生命周期方法。

    1. constructor()
    2. static getDerivedStateFromProps()
    3. render()
    4. componentDidMount()

返回页首

  1. React v16 中将弃用哪些生命周期方法?

    以下生命周期方法将是不安全的编码实践,并且异步渲染将带来更多问题。

    1. componentWillMount()
    2. componentWillReceiveProps()
    3. componentWillUpdate()

    从 React v16.3 开始,这些方法都带有前缀,无前缀的版本将在 React v17 中删除。

    UNSAFE_

返回页首

  1. 生命周期法的目的是什么?
    getDerivedStateFromProps()

    新的静态生命周期方法在组件实例化之后以及重新呈现之前调用。它可以返回一个对象来更新状态,或者指示新 props 不需要任何状态更新。

    getDerivedStateFromProps()
    null

    class MyComponent extends React.Component {
      static getDerivedStateFromProps(props, state) {
        // ...
      }
    }

    此生命周期方法以及 涵盖了 的所有用例。

    componentDidUpdate()
    componentWillReceiveProps()

返回页首

  1. 生命周期法的目的是什么?
    getSnapshotBeforeUpdate()

    新的生命周期方法在 DOM 更新之前调用。此方法的返回值将作为第三个参数传递给 。

    getSnapshotBeforeUpdate()
    componentDidUpdate()

    class MyComponent extends React.Component {
      getSnapshotBeforeUpdate(prevProps, prevState) {
        // ...
      }
    }

    此生命周期方法以及 涵盖了 的所有用例。

    componentDidUpdate()
    componentWillUpdate()

返回页首

  1. 钩子会取代渲染道具和高阶组件吗?

    渲染道具和高阶组件都只渲染一个子组件,但在大多数情况下,Hooks 是一种更简单的方法,可以通过减少树中的嵌套来提供这种服务。

返回页首

  1. 建议的组件命名方法是什么?

    建议通过引用而不是使用 .

    displayName

    用于命名组件:

    displayName

    export default React.createClass({
      displayName: 'TodoApp',
      // ...
    })

    推荐的方法:

    export default class TodoApp extends React.Component {
      // ...
    }

    const TodoApp = () => {
     //...
    }
    export default TodoApp;

返回页首

  1. 组件类中方法的建议顺序是什么?

    建议挂载渲染阶段的方法顺序:

    1. static
      方法
    2. constructor()
    3. getChildContext()
    4. componentWillMount()
    5. componentDidMount()
    6. componentWillReceiveProps()
    7. shouldComponentUpdate()
    8. componentWillUpdate()
    9. componentDidUpdate()
    10. componentWillUnmount()
    11. 单击处理程序或事件处理程序,例如 或
      onClickSubmit()
      onChangeDescription()
    12. 用于渲染的 getter 方法
      getSelectReason()
      getFooterContent()
    13. 可选的呈现方法,如 或
      renderNavigation()
      renderProfilePicture()
    14. render()

返回页首

  1. 什么是开关元件?

    切换组件是呈现许多组件之一的组件。我们需要使用 object 将 prop 值映射到组件。

    例如,一个切换组件,用于根据 prop 显示不同的页面:

    page

    import HomePage from './HomePage'
    import AboutPage from './AboutPage'
    import ServicesPage from './ServicesPage'
    import ContactPage from './ContactPage'
    
    const PAGES = {
      home: HomePage,
      about: AboutPage,
      services: ServicesPage,
      contact: ContactPage
    }
    
    const Page = (props) => {
      const Handler = PAGES[props.page] || ContactPage
    
      return <Handler {...props} />
    }
    
    // The keys of the PAGES object can be used in the prop types to catch dev-time errors.
    Page.propTypes = {
      page: PropTypes.oneOf(Object.keys(PAGES)).isRequired
    }

返回页首

  1. 为什么我们需要将函数传递给 setState()?

    其背后的原因是这是一个异步操作。React 批处理状态出于性能原因而更改,因此状态可能不会在调用后立即更改。这意味着在调用时不应依赖当前状态,因为你无法确定该状态是什么。解决方案是将函数传递给 ,并将以前的状态作为参数。通过这样做,可以避免由于 的异步性质而导致用户在访问时获取旧状态值的问题。

    setState()
    setState()
    setState()
    setState()
    setState()

    假设初始计数值为零。连续三次增量操作后,该值将仅递增 1。

    // assuming this.state.count === 0
    this.setState({ count: this.state.count + 1 })
    this.setState({ count: this.state.count + 1 })
    this.setState({ count: this.state.count + 1 })
    // this.state.count === 1, not 3

    如果我们将一个函数传递给 ,计数将正确递增。

    setState()

    this.setState((prevState, props) => ({
      count: prevState.count + props.increment
    }))
    // this.state.count === 3 as expected

    (或)

    为什么函数优先于对象?
    setState()

    React 可以将多个调用批处理到单个更新中以提高性能。由于 和 可能会异步更新,因此不应依赖它们的值来计算下一个状态。

    setState()
    this.props
    this.state

    此计数器示例将无法按预期更新:

    // Wrong
    this.setState({
      counter: this.state.counter + this.props.increment,
    })

    首选方法是使用函数而不是对象进行调用。该函数将接收以前的状态作为第一个参数,并将应用更新时的 props 作为第二个参数接收。

    setState()

    // Correct
    this.setState((prevState, props) => ({
      counter: prevState.counter + props.increment
    }))

返回页首

  1. 什么是 React 中的严格模式?

    React.StrictMode
    是突出显示应用程序中潜在问题的有用组件。就像 一样,不渲染任何额外的 DOM 元素。它会为其后代激活其他检查和警告。这些检查仅适用于开发模式
    <Fragment>
    <StrictMode>

    import React from 'react'
    
    function ExampleApplication() {
      return (
        <div>
          <Header />
          <React.StrictMode>
            <div>
              <ComponentOne />
              <ComponentTwo />
            </div>
          </React.StrictMode>
          <Header />
        </div>
      )
    }

    在上面的示例中,严格模式检查仅适用于 和 组件。

    <ComponentOne>
    <ComponentTwo>

返回页首

  1. 什么是 React Mixins?

    Mixins 是一种将组件完全分离以具有通用功能的方法。不应使用混合,可以用更高阶的组件装饰器代替。

    最常用的混合之一是。你可能会在某些组件中使用它,以防止当 props 和状态与以前的 props 和状态浅相等时进行不必要的重新渲染:

    PureRenderMixin

    const PureRenderMixin = require('react-addons-pure-render-mixin')
    
    const Button = React.createClass({
      mixins: [PureRenderMixin],
      // ...
    })

返回页首

  1. 为什么是反模式,正确的解决方案是什么?
    isMounted()

    主要用例是避免在卸载组件后调用,因为它会发出警告。

    isMounted()
    setState()

    if (this.isMounted()) {
      this.setState({...})
    }

    在调用之前进行检查确实会消除警告,但它也违背了警告的目的。使用 是一种代码异味,因为你要检查的唯一原因是你认为在组件卸载后你可能持有引用。

    isMounted()
    setState()
    isMounted()

    最佳解决方案是找到在组件卸载后可能调用的位置,并修复它们。这种情况最常由于回调而发生,当组件正在等待某些数据并在数据到达之前被卸载时。理想情况下,在卸载之前,应在 中取消任何回调。

    setState()
    componentWillUnmount()

返回页首

  1. React 支持哪些指针事件?

    指针事件提供处理所有输入事件的统一方法。在过去,我们有一个鼠标和各自的事件侦听器来处理它们,但现在我们有许多与鼠标无关的设备,例如带有触摸表面或笔的手机。我们需要记住,这些事件仅在支持指针事件规范的浏览器中有效。

    以下事件类型现在在 React DOM 中可用:

    1. onPointerDown
    2. onPointerMove
    3. onPointerUp
    4. onPointerCancel
    5. onGotPointerCapture
    6. onLostPointerCapture
    7. onPointerEnter
    8. onPointerLeave
    9. onPointerOver
    10. onPointerOut

返回页首

  1. 为什么组件名称应该以大写字母开头?

    如果你使用 JSX 渲染你的组件,该组件的名称必须以大写字母开头,否则 React 将抛出错误作为无法识别的标签。此约定是因为只有 HTML 元素和 SVG 标记可以以小写字母开头。

    class SomeComponent extends Component {
     // Code goes here
    }

    你可以定义名称以小写字母开头的组件类,但在导入时应具有大写字母。这里小写很好:

    class myComponent extends Component {
      render() {
        return <div />
      }
    }
    
    export default myComponent

    而在另一个文件中导入时,它应该以大写字母开头:

    import MyComponent from './myComponent'

    React 组件命名有哪些例外?

    组件名称应以大写字母开头,但此约定很少有例外。带有点(属性访问器)的小写标记名称仍被视为有效的组件名称。例如,下面的标签可以编译成一个有效的组件,

         render() {
              return (
                <obj.component/> // `React.createElement(obj.component)`
              )
        }

返回页首

  1. React v16 是否支持自定义 DOM 属性?

    是的。过去,React 曾经忽略未知的 DOM 属性。如果你用 React 无法识别的属性编写 JSX,React 会跳过它。

    例如,让我们看一下下面的属性:

    <div mycustomattribute={'something'} />

    将使用 React v15 向 DOM 渲染一个空的 div:

    <div />

    在 React v16 中,任何未知属性都将出现在 DOM 中:

    <div mycustomattribute='something' />

    这对于提供特定于浏览器的非标准属性、尝试新的 DOM API 以及与固执己见的第三方库集成非常有用。

返回页首

  1. 构造函数和getInitialState有什么区别?

    使用 ES6 类时,应在构造函数中初始化状态,在使用 .

    getInitialState()
    React.createClass()

    使用 ES6 类:

    class MyComponent extends React.Component {
      constructor(props) {
        super(props)
        this.state = { /* initial state */ }
      }
    }

    使用 React.createClass():

    const MyComponent = React.createClass({
      getInitialState() {
        return { /* initial state */ }
      }
    })

    注意:在 React v16 中已弃用并删除。改用普通的 JavaScript 类。

    React.createClass()

返回页首

  1. 是否可以在不调用 setState 的情况下强制组件重新渲染?

    默认情况下,当组件的状态或 props 发生变化时,组件将重新渲染。如果你的方法依赖于其他一些数据,你可以通过调用 来告诉 React 组件需要重新渲染。

    render()
    forceUpdate()

    component.forceUpdate(callback)

    建议避免使用 和仅从 和 中读取。

    forceUpdate()
    this.props
    this.state
    render()

返回页首

  1. 使用 ES6 类的 React 之间和 React 有什么区别?
    super()
    super(props)

    当你想进入时,你应该将道具传递给方法。

    this.props
    constructor()
    super()

    使用超级(道具):

    class MyComponent extends React.Component {
      constructor(props) {
        super(props)
        console.log(this.props) // { name: 'John', ... }
      }
    }

    使用 super():

    class MyComponent extends React.Component {
      constructor(props) {
        super()
        console.log(this.props) // undefined
      }
    }

    在两者之外将显示相同的值。

    constructor()
    this.props

返回页首

  1. 如何在 JSX 内部循环?

    你可以简单地使用 ES6 箭头函数语法。

    Array.prototype.map

    例如,对象数组映射到组件数组:

    items

    <tbody>
      {items.map(item => <SomeComponent key={item.id} name={item.name} />)}
    </tbody>

    但是你不能使用循环进行迭代:

    for

    <tbody>
      for (let i = 0; i < items.length; i++) {
        <SomeComponent key={items[i].id} name={items[i].name} />
      }
    </tbody>

    这是因为 JSX 标记被转译为函数调用,并且不能在表达式中使用语句。由于第一阶段提案的表达方式,这可能会改变。

    do

返回页首

  1. 如何访问属性引号中的道具?

    React (或 JSX) 不支持属性值内的变量插值。以下表示法不起作用:

    <img className='image' src='images/{this.props.image}' />

    但是你可以将任何 JS 表达式作为整个属性值放在大括号内。所以下面的表达式有效:

    <img className='image' src={'images/' + this.props.image} />

    使用模板字符串也可以:

    <img className='image' src={`images/${this.props.image}`} />

返回页首

  1. 什么是带有形状的 React 属性类型数组?

    如果要将对象数组传递给具有特定形状的组件,请使用 的参数。

    React.PropTypes.shape()
    React.PropTypes.arrayOf()

    ReactComponent.propTypes = {
      arrayWithShape: React.PropTypes.arrayOf(React.PropTypes.shape({
        color: React.PropTypes.string.isRequired,
        fontSize: React.PropTypes.number.isRequired
      })).isRequired
    }

返回页首

  1. 如何有条件地应用类属性?

    你不应该在引号内使用大括号,因为它将被计算为字符串。

    <div className="btn-panel {this.props.visible ? 'show' : 'hidden'}">

    相反,你需要将大括号移到外面(不要忘记在类名之间包含空格):

    <div className={'btn-panel ' + (this.props.visible ? 'show' : 'hidden')}>

    模板字符串也将起作用:

    <div className={`btn-panel ${this.props.visible ? 'show' : 'hidden'}`}>

返回页首

  1. React 和 ReactDOM 有什么区别?

    包包含 、、 以及与元素和组件类相关的其他帮助程序。你可以将这些视为构建组件所需的同构或通用帮助程序。该包包含 ,并且我们在服务器端渲染支持 和 .

    react
    React.createElement()
    React.Component
    React.Children
    react-dom
    ReactDOM.render()
    react-dom/server
    ReactDOMServer.renderToString()
    ReactDOMServer.renderToStaticMarkup()

返回页首

  1. 为什么 ReactDOM 与 React 分离?

    React 团队致力于将所有与 DOM 相关的功能提取到一个名为 ReactDOM 的独立库中。React v0.14 是第一个拆分库的版本。通过查看一些软件包,、、 和 ,很明显,React 的美感和本质与浏览器或 DOM 无关。

    react-native
    react-art
    react-canvas
    react-three

    为了构建更多 React 可以渲染的环境,React 团队计划将主 React 包拆分为两个:和 .这为编写可以在 React 和 React Native 的 Web 版本之间共享的组件铺平了道路。

    react
    react-dom

返回页首

  1. 如何使用 React 标签元素?

    如果尝试使用标准属性呈现绑定到文本输入的元素,则会生成缺少该属性的 HTML,并将警告打印到控制台。

    <label>
    for

    <label for={'user'}>{'User'}</label>
    <input type={'text'} id={'user'} />

    由于是 JavaScript 中的保留关键字,请改用。

    for
    htmlFor

    <label htmlFor={'user'}>{'User'}</label>
    <input type={'text'} id={'user'} />

返回页首

  1. 如何组合多个内联样式对象?

    你可以在常规 React 中使用点差运算符

     <button style={{...styles.panel.button, ...styles.panel.submitButton}}>{'Submit'}</button>

    如果你使用的是 React Native,那么你可以使用数组符号:

    <button style={[styles.panel.button, styles.panel.submitButton]}>{'Submit'}</button>

返回页首

  1. 调整浏览器大小时如何重新呈现视图?

    你可以在 中侦听事件,然后更新维度 ( 和 )。你应该在方法中删除侦听器。

    resize
    componentDidMount()
    width
    height
    componentWillUnmount()

    class WindowDimensions extends React.Component {
      constructor(props){
        super(props);
        this.updateDimensions = this.updateDimensions.bind(this);
      }
       
      componentWillMount() {
        this.updateDimensions()
      }
    
      componentDidMount() {
        window.addEventListener('resize', this.updateDimensions)
      }
    
      componentWillUnmount() {
        window.removeEventListener('resize', this.updateDimensions)
      }
    
      updateDimensions() {
        this.setState({width: window.innerWidth, height: window.innerHeight})
      }
    
      render() {
        return <span>{this.state.width} x {this.state.height}</span>
      }
    }

返回页首

  1. 和方法有什么区别?
    setState()
    replaceState()

    当你使用当前状态和以前的状态时,将合并。 抛弃当前状态,并仅将其替换为你提供的状态。通常使用,除非你出于某种原因确实需要删除所有以前的密钥。你还可以将状态设置为 / in 而不是使用 。

    setState()
    replaceState()
    setState()
    false
    null
    setState()
    replaceState()

返回页首

  1. 如何监听状态变化?

    当状态更改时,将调用生命周期方法。你可以将提供的状态和 props 值与当前状态和 props 进行比较,以确定是否发生了有意义的更改。

    componentDidUpdate

    componentDidUpdate(object prevProps, object prevState)
    

    注意:ReactJS的先前版本也用于状态更改。它在最新版本中已弃用。

    componentWillUpdate(object nextProps, object nextState)

返回页首

  1. 删除 React 状态的数组元素的推荐方法是什么?

    更好的方法是使用方法。

    Array.prototype.filter()

    例如,让我们创建一个用于更新状态的方法。

    removeItem()

    removeItem(index) {
      this.setState({
        data: this.state.data.filter((item, i) => i !== index)
      })
    }

返回页首

  1. 是否可以在不渲染 HTML 的情况下使用 React?

    最新版本(>=16.2)是可能的。以下是可能的选项:

    render() {
      return false
    }
    render() {
      return null
    }
    render() {
      return []
    }
    render() {
      return <React.Fragment></React.Fragment>
    }
    render() {
      return <></>
    }

    返回是行不通的。

    undefined

返回页首

  1. 如何使用 React 漂亮地打印 JSON?

    我们可以使用标签来保留 的格式:

    <pre>
    JSON.stringify()

    const data = { name: 'John', age: 42 }
    
    class User extends React.Component {
      render() {
        return (
          <pre>
            {JSON.stringify(data, null, 2)}
          </pre>
        )
      }
    }
    
    React.render(<User />, document.getElementById('container'))

返回页首

  1. 为什么你不能在 React 中更新道具?

    React 的理念是道具应该是不可变的和自上而下的。这意味着父母可以将任何道具值发送给孩子,但孩子不能修改收到的道具。

返回页首

  1. 如何在页面加载时聚焦输入元素?

    你可以通过为元素创建 ref 并在 :

    input
    componentDidMount()

    class App extends React.Component{
      componentDidMount() {
        this.nameInput.focus()
      }
    
      render() {
        return (
          <div>
            <input
              defaultValue={'Won\'t focus'}
            />
            <input
              ref={(input) => this.nameInput = input}
              defaultValue={'Will focus'}
            />
          </div>
        )
      }
    }
    
    ReactDOM.render(<App />, document.getElementById('app'))

    也在功能组件中( React 16.08 及以上)

    import React, {useEffect, useRef} from 'react';
    
    const App = () => {
      const inputElRef = useRef(null)
      
      useEffect(()=>{
        inputElRef.current.focus()
      }, [])
      
      return(
        <div>
          <input
            defaultValue={'Won\'t focus'}
          />
          <input
            ref={inputElRef}
            defaultValue={'Will focus'}
          />
        </div>
      )
    }
    
    ReactDOM.render(<App />, document.getElementById('app'))

返回页首

  1. 更新状态中的对象的可能方法有哪些?

    1. 调用 setState() 与要与状态合并的对象:

      • 用于创建对象的副本:

        Object.assign()

        const user = Object.assign({}, this.state.user, { age: 42 })
        this.setState({ user })
      • 使用点差运算符

        const user = { ...this.state.user, age: 42 }
        this.setState({ user })
    2. 使用函数调用 setState():

      this.setState(prevState => ({
        user: {
          ...prevState.user,
          age: 42
        }
      }))

返回页首

  1. 我们如何在浏览器中找到运行时的 React 版本?

    你可以使用 获取版本。

    React.version

    const REACT_VERSION = React.version
    
    ReactDOM.render(
      <div>{`React version: ${REACT_VERSION}`}</div>,
      document.getElementById('app')
    )

返回页首

  1. 有哪些方法可以在你的 ?
    create-react-app

    有一些方法可以在创建- React -应用程序中包含 polyfill,

    1. core-js手动导入:

      创建一个名为(类似)的文件并将其导入根文件。运行或导入特定的必需功能。

      polyfills.js
      index.js
      npm install core-js
      yarn add core-js

      import 'core-js/fn/array/find'
      import 'core-js/fn/array/includes'
      import 'core-js/fn/number/is-nan'
    2. 使用多边形填充服务:

      使用 polyfill.io CDN 检索自定义的、特定于浏览器的 polyfill,方法是将此行添加到:

      index.html

      <script src='https://cdn.polyfill.io/v2/polyfill.min.js?features=default,Array.prototype.includes'></script>

      在上面的脚本中,我们必须显式请求该功能,因为它不包含在默认功能集中。

      Array.prototype.includes

返回页首

  1. 如何在create-react-app中使用https而不是http?

    你只需要使用配置。你可以编辑脚本部分:

    HTTPS=true
    package.json

    "scripts": {
      "start": "set HTTPS=true && react-scripts start"
    }

    或者只是运行

    set HTTPS=true && npm start

返回页首

  1. 如何避免在创建- React -应用中使用相对路径导入?

    创建一个在项目根目录中调用的文件并写入导入路径:

    .env

    NODE_PATH=src/app
    

    之后重新启动开发服务器。现在,你应该能够在没有相对路径的情况下导入任何内容。

    src/app

返回页首

  1. 如何为 React Router 添加 Google Analytics?

    在对象上添加侦听器以记录每个页面视图:

    history

    history.listen(function (location) {
      window.ga('set', 'page', location.pathname + location.search)
      window.ga('send', 'pageview', location.pathname + location.search)
    })

返回页首

  1. 如何每秒更新一个组件?

    你需要使用 来触发更改,但你还需要在组件卸载时清除计时器,以防止错误和内存泄漏。

    setInterval()

    componentDidMount() {
      this.interval = setInterval(() => this.setState({ time: Date.now() }), 1000)
    }
    
    componentWillUnmount() {
      clearInterval(this.interval)
    }

返回页首

  1. 如何将供应商前缀应用于 React 中的内联样式?

    React 不会自动应用供应商前缀。你需要手动添加供应商前缀。

    <div style={{
      transform: 'rotate(90deg)',
      WebkitTransform: 'rotate(90deg)', // note the capital 'W' here
      msTransform: 'rotate(90deg)' // 'ms' is the only lowercase vendor prefix
    }} />

返回页首

  1. 如何使用 React 和 ES6 导入和导出组件?

    应使用默认值导出组件

    import React from 'react'
    import User from 'user'
    
    export default class MyProfile extends React.Component {
      render(){
        return (
          <User type="customer">
            //...
          </User>
        )
      }
    }

    使用导出说明符,MyProfile 将成为成员并导出到此模块,并且可以导入相同的内容,而无需在其他组件中提及名称。

返回页首

  1. 为什么组件构造函数只调用一次?

    React 的协调算法假设在没有任何相反信息的情况下,如果自定义组件在后续渲染中出现在同一位置,则它与以前的组件相同,因此重用以前的实例而不是创建新实例。

返回页首

  1. 如何在 React 中定义常量?

    你可以使用 ES7 字段来定义常量。

    static

    class MyComponent extends React.Component {
      static DEFAULT_PAGINATION = 10
    }

返回页首

  1. 如何在 React 中以编程方式触发点击事件?

    可以使用 ref 属性通过回调获取对基础对象的引用,将引用存储为类属性,然后使用该引用稍后使用该方法触发事件处理程序的单击。

    HTMLInputElement
    HTMLElement.click

    这可以通过两个步骤完成:

    1. 在渲染方法中创建引用:

      <input ref={input => this.inputElement = input} />
    2. 在事件处理程序中应用 click 事件:

      this.inputElement.click()

返回页首

  1. 是否可以在普通 React 中使用 async/await?

    如果你想在 React 中使用 /,你将需要 Babeltransform-async-to-generator 插件。React Native 附带 Babel 和一组变换。

    async
    await

返回页首

  1. React 的常见文件夹结构是什么?

    React 项目文件结构有两种常见的做法。

    1. 按要素或路径分组:

      构建项目的一种常见方法是将 CSS、JS 和测试放在一起,按功能或路由分组。

      common/
      ├─ Avatar.js
      ├─ Avatar.css
      ├─ APIUtils.js
      └─ APIUtils.test.js
      feed/
      ├─ index.js
      ├─ Feed.js
      ├─ Feed.css
      ├─ FeedStory.js
      ├─ FeedStory.test.js
      └─ FeedAPI.js
      profile/
      ├─ index.js
      ├─ Profile.js
      ├─ ProfileHeader.js
      ├─ ProfileHeader.css
      └─ ProfileAPI.js
      
    2. 按文件类型分组:

      构建项目的另一种流行方法是将类似的文件组合在一起。

      api/
      ├─ APIUtils.js
      ├─ APIUtils.test.js
      ├─ ProfileAPI.js
      └─ UserAPI.js
      components/
      ├─ Avatar.js
      ├─ Avatar.css
      ├─ Feed.js
      ├─ Feed.css
      ├─ FeedStory.js
      ├─ FeedStory.test.js
      ├─ Profile.js
      ├─ ProfileHeader.js
      └─ ProfileHeader.css
      

返回页首

  1. 流行的动画包有哪些?

    React Transition Group 和 React Motion 是 React 生态系统中流行的动画包。

返回页首

  1. 样式模块有什么好处?

    建议避免在组件中硬编码样式值。可能跨不同 UI 组件使用的任何值都应提取到其自己的模块中。

    例如,可以将这些样式提取到单独的组件中:

    export const colors = {
      white,
      black,
      blue
    }
    
    export const space = [
      0,
      8,
      16,
      32,
      64
    ]

    然后在其他组件中单独导入:

    import { space, colors } from './styles'

返回页首

  1. 什么是流行的 React 专用短绒?

    ESLint 是一种流行的 JavaScript linter。有一些插件可以分析特定的代码样式。React 最常见的一个是一个名为 的 npm 包。默认情况下,它将检查许多最佳实践,规则检查从迭代器中的键到一组完整的道具类型。

    eslint-plugin-react

    另一个流行的插件是 ,这将有助于解决可访问性的常见问题。由于JSX提供的语法与常规HTML略有不同,因此文本和问题(例如)不会被常规插件拾取。

    eslint-plugin-jsx-a11y
    alt
    tabindex

返回页首

  1. 如何进行 AJAX 调用以及我应该在哪些组件生命周期方法中进行 AJAX 调用?

    你可以使用 AJAX 库,例如 Axios、jQuery AJAX 和浏览器内置的 .你应该在生命周期方法中获取数据。这样你就可以在检索数据时用于更新组件。

    fetch
    componentDidMount()
    setState()

    例如,从 API 获取的员工列表并设置本地状态:

    class MyComponent extends React.Component {
      constructor(props) {
        super(props)
        this.state = {
          employees: [],
          error: null
        }
      }
    
      componentDidMount() {
        fetch('https://api.example.com/items')
          .then(res => res.json())
          .then(
            (result) => {
              this.setState({
                employees: result.employees
              })
            },
            (error) => {
              this.setState({ error })
            }
          )
      }
    
      render() {
        const { error, employees } = this.state
        if (error) {
          return <div>Error: {error.message}</div>;
        } else {
          return (
            <ul>
              {employees.map(employee => (
                <li key={employee.name}>
                  {employee.name}-{employee.experience}
                </li>
              ))}
            </ul>
          )
        }
      }
    }

返回页首

  1. 什么是渲染道具?

    渲染道具是一种简单的技术,用于使用值为函数的道具在组件之间共享代码。下面的组件使用返回 React 元素的渲染属性。

    <DataProvider render={data => (
      <h1>{`Hello ${data.target}`}</h1>
    )}/>

    像React Router和DownShift这样的库正在使用这种模式。

React 路由器

返回页首

  1. 什么是 React Router?

    React Router 是一个建立在 React 之上的强大路由库,可帮助你以令人难以置信的速度添加新屏幕和流到你的应用程序中,同时保持 URL 与页面上显示的内容同步。

返回页首

  1. React Router 与历史库有何不同?

    React Router 是库的包装器,它处理与浏览器及其浏览器和哈希历史记录的交互。它还提供内存历史记录,这对于没有全局历史记录的环境很有用,例如移动应用程序开发(React Native)和使用 Node 进行单元测试。

    history
    window.history

返回页首

  1. React Router v4 的组件是什么?
    <Router>

    React Router v4 提供以下 3 个组件:

    <Router>

    1. <BrowserRouter>
    2. <HashRouter>
    3. <MemoryRouter>

    上述组件将创建浏览器哈希内存历史记录实例。React Router v4 使与路由器关联的实例的属性和方法通过对象中的上下文可用。

    history
    router

返回页首

  1. 的目的和方法是什么?
    push()
    replace()
    history

    历史记录实例有两种用于导航的方法。

    1. push()
    2. replace()

    如果将历史记录视为访问过的位置的数组, 将向数组添加一个新位置,并将数组中的当前位置替换为新位置。

    push()
    replace()

返回页首

  1. 如何使用 React Router v4 以编程方式导航?

    有三种不同的方法可以在组件内实现编程路由/导航。

    1. 使用 withRouter() 高阶函数:

      高阶函数会将历史对象作为组件的道具注入。此对象提供 和 方法来避免使用上下文。

      withRouter()
      push()
      replace()

      import { withRouter } from 'react-router-dom' // this also works with 'react-router-native'
      
      const Button = withRouter(({ history }) => (
        <button
          type='button'
          onClick={() => { history.push('/new-location') }}
        >
          {'Click Me!'}
        </button>
      ))
    2. 使用 <Route> 组件和渲染道具模式:

      该组件传递与 相同的 props,因此你将能够通过 history prop 访问 history 方法。

      <Route>
      withRouter()

      import { Route } from 'react-router-dom'
      
      const Button = () => (
        <Route render={({ history }) => (
          <button
            type='button'
            onClick={() => { history.push('/new-location') }}
          >
            {'Click Me!'}
          </button>
        )} />
      )
    3. 使用上下文:

      不建议使用此选项,并将其视为不稳定的 API。

      const Button = (props, context) => (
        <button
          type='button'
          onClick={() => {
            context.history.push('/new-location')
          }}
        >
          {'Click Me!'}
        </button>
      )
      
      Button.contextTypes = {
        history: React.PropTypes.shape({
          push: React.PropTypes.func.isRequired
        })
      }

返回页首

  1. 如何在 React Router v4 中获取查询参数?

    解析查询字符串的功能是从 React Router v4 中移除的,因为多年来一直有用户请求支持不同的实现。因此,已经决定用户选择他们喜欢的实现。建议的方法是使用查询字符串库。

    const queryString = require('query-string');
    const parsed = queryString.parse(props.location.search);

    如果你想要一些原生的东西,你也可以使用:

    URLSearchParams

    const params = new URLSearchParams(props.location.search)
    const foo = params.get('name')

    应为 IE11 使用填充代码

返回页首

  1. 为什么收到“路由器可能只有一个子元素”警告?

    你必须将路由包装在一个块中,因为它是唯一的,因为它以独占方式呈现路由。

    <Switch>
    <Switch>

    首先,你需要添加到导入中:

    Switch

    import { Switch, Router, Route } from 'react-router'

    然后在块内定义路由:

    <Switch>

    <Router>
      <Switch>
        <Route {/* ... */} />
        <Route {/* ... */} />
      </Switch>
    </Router>

返回页首

  1. 如何将参数传递给 React Router v4 中的方法?
    history.push

    导航时,你可以将道具传递给对象:

    history

    this.props.history.push({
      pathname: '/template',
      search: '?name=sudheer',
      state: { detail: response.data }
    })

    该属性用于在方法中传递查询参数。

    search
    push()

返回页首

  1. 如何实现默认未找到页面?

    A 呈现匹配的第一个子项。没有路径的 A 始终匹配。所以你只需要简单地删除路径属性,如下所示

    <Switch>
    <Route>
    <Route>

    <Switch>
      <Route exact path="/" component={Home}/>
      <Route path="/user" component={User}/>
      <Route component={NotFound} />
    </Switch>

返回页首

  1. 如何在 React Router v4 上获取历史记录?

    以下是在 React Router v4 上获取历史对象的步骤列表,

    1. 创建一个导出对象的模块,并在整个项目中导入此模块。

      history

      例如,创建文件:

      history.js

      import { createBrowserHistory } from 'history'
      
      export default createBrowserHistory({
        /* pass a configuration object here if needed */
      })
    2. 你应该使用该组件而不是内置路由器。导入上述内部文件:

      <Router>
      history.js
      index.js

      import { Router } from 'react-router-dom'
      import history from './history'
      import App from './App'
      
      ReactDOM.render((
        <Router history={history}>
          <App />
        </Router>
      ), holder)
    3. 你也可以使用类似于内置历史对象的推送方法:

      history

      // some-other-file.js
      import history from './history'
      
      history.push('/go-here')

返回页首

  1. 登录后如何执行自动重定向?

    该软件包在 React Router 中提供了组件。渲染将导航到新位置。与服务器端重定向一样,新位置将覆盖历史记录堆栈中的当前位置。

    react-router
    <Redirect>
    <Redirect>

    import React, { Component } from 'react'
    import { Redirect } from 'react-router'
    
    export default class LoginComponent extends Component {
      render() {
        if (this.state.isLoggedIn === true) {
          return <Redirect to="/your/redirect/page" />
        } else {
          return <div>{'Login Please'}</div>
        }
      }
    }

React 国际化

返回页首

  1. 什么是 React 国际机场?

    React Intl 库使 React 中的国际化变得简单明了,具有现成的组件和 API,可以处理从格式化字符串、日期和数字到复数的所有内容。React Intl 是 FormatJS 的一部分,它通过其组件和 API 提供与 React 的绑定。

返回页首

  1. React Intl的主要特点是什么?

    以下是 React Intl 的主要功能,

    1. 用分隔符显示数字。
    2. 正确显示日期和时间。
    3. 显示相对于“现在”的日期。
    4. 将字符串中的标签复数化。
    5. 支持 150+ 种语言。
    6. 在浏览器和节点中运行。
    7. 建立在标准之上。

返回页首

  1. 在 React Intl 中格式化的两种方法是什么?

    该库提供了两种设置字符串、数字和日期格式的方法:

    1. 使用 react 组件:

      <FormattedMessage
        id={'account'}
        defaultMessage={'The amount is less than minimum balance.'}
      />
    2. 使用 API:

      const messages = defineMessages({
        accountMessage: {
          id: 'account',
          defaultMessage: 'The amount is less than minimum balance.',
        }
      })
      
      formatMessage(messages.accountMessage)

返回页首

  1. 如何使用 React Intl 用作占位符?
    <FormattedMessage>

    返回元素中的组件,而不是纯文本,因此它们不能用于占位符、替代文本等。在这种情况下,你应该使用 较低级别的 API .你可以使用高阶组件将对象注入到组件中,然后使用该对象上的 available 格式化消息。

    <Formatted... />
    react-intl
    formatMessage()
    intl
    injectIntl()
    formatMessage()

    import React from 'react'
    import { injectIntl, intlShape } from 'react-intl'
    
    const MyComponent = ({ intl }) => {
      const placeholder = intl.formatMessage({id: 'messageId'})
      return <input placeholder={placeholder} />
    }
    
    MyComponent.propTypes = {
      intl: intlShape.isRequired
    }
    
    export default injectIntl(MyComponent)

返回页首

  1. 如何使用 React Intl 访问当前语言环境?

    你可以使用以下命令获取应用程序的任何组件中的当前区域设置:

    injectIntl()

    import { injectIntl, intlShape } from 'react-intl'
    
    const MyComponent = ({ intl }) => (
      <div>{`The current locale is ${intl.locale}`}</div>
    )
    
    MyComponent.propTypes = {
      intl: intlShape.isRequired
    }
    
    export default injectIntl(MyComponent)

返回页首

  1. 如何使用 React 国际机场格式化日期?

    高阶组件将允许你通过组件中的 props 访问该方法。该方法由 的实例在内部使用,并返回格式化日期的字符串表示形式。

    injectIntl()
    formatDate()
    FormattedDate

    import { injectIntl, intlShape } from 'react-intl'
    
    const stringDate = this.props.intl.formatDate(date, {
      year: 'numeric',
      month: 'numeric',
      day: 'numeric'
    })
    
    const MyComponent = ({intl}) => (
      <div>{`The formatted date is ${stringDate}`}</div>
    )
    
    MyComponent.propTypes = {
      intl: intlShape.isRequired
    }
    
    export default injectIntl(MyComponent)

React 测试

返回页首

  1. 什么是 React 测试中的浅层渲染器?

    浅表渲染对于在 React 中编写单元测试用例很有用。它允许你将组件呈现一个级别深,并断言有关其呈现方法返回的内容的事实,而无需担心未实例化或呈现的子组件的行为。

    例如,如果你有以下组件:

    function MyComponent() {
      return (
        <div>
          <span className={'heading'}>{'Title'}</span>
          <span className={'description'}>{'Description'}</span>
        </div>
      )
    }

    然后你可以断言如下:

    import ShallowRenderer from 'react-test-renderer/shallow'
    
    // in your test
    const renderer = new ShallowRenderer()
    renderer.render(<MyComponent />)
    
    const result = renderer.getRenderOutput()
    
    expect(result.type).toBe('div')
    expect(result.props.children).toEqual([
      <span className={'heading'}>{'Title'}</span>,
      <span className={'description'}>{'Description'}</span>
    ])

返回页首

  1. 什么是 React 中的包?
    TestRenderer

    此包提供了一个渲染器,可用于将组件渲染为纯 JavaScript 对象,而无需依赖 DOM 或本机移动环境。这个包可以很容易地抓取由 ReactDOM 或 React Native 渲染的平台视图层次结构(类似于 DOM 树)的快照,而无需使用浏览器或 .

    jsdom

    import TestRenderer from 'react-test-renderer'
    
    const Link = ({page, children}) => <a href={page}>{children}</a>
    
    const testRenderer = TestRenderer.create(
      <Link page={'https://www.facebook.com/'}>{'Facebook'}</Link>
    )
    
    console.log(testRenderer.toJSON())
    // {
    //   type: 'a',
    //   props: { href: 'https://www.facebook.com/' },
    //   children: [ 'Facebook' ]
    // }

返回页首

  1. ReactTestUtils软件包的目的是什么?

    ReactTestUtils 在包中提供,允许你针对模拟 DOM 执行操作以进行单元测试。

    with-addons

返回页首

  1. 什么是开玩笑?

    Jest是Facebook基于Jasmine创建的JavaScript单元测试框架,并提供自动模拟创建和环境。它通常用于测试组件。

    jsdom

返回页首

  1. 开玩笑与茉莉花相比有什么优势?

    与茉莉花相比,有几个优点:

    • 自动查找要在源代码中执行的测试。
    • 在运行测试时自动模拟依赖项。
    • 允许你同步测试异步代码。
    • 使用假 DOM 实现(通过)运行测试,以便可以在命令行上运行测试。
      jsdom
    • 在并行进程中运行测试,以便它们更快地完成。

返回页首

  1. 举一个简单的Jest测试用例的例子

    让我们为一个在文件中将两个数字相加的函数编写一个测试:

    sum.js

    const sum = (a, b) => a + b
    
    export default sum

    创建一个包含实际测试的文件名:

    sum.test.js

    import sum from './sum'
    
    test('adds 1 + 2 to equal 3', () => {
      expect(sum(1, 2)).toBe(3)
    })

    然后将以下部分添加到你的:

    package.json

    {
      "scripts": {
        "test": "jest"
      }
    }

    最后,运行或和 Jest 将打印一个结果:

    yarn test
    npm test

    $ yarn test
    PASS ./sum.test.js
    ✓ adds 1 + 2 to equal 3 (2ms)

React Redux

返回页首

  1. 什么是助焊剂?

    Flux 是一种应用程序设计范例,用于替代更传统的 MVC 模式。它不是一个框架或库,而是一种新型架构,补充了 React 和单向数据流的概念。Facebook 在使用 React 时在内部使用此模式。

    调度程序、存储和查看具有不同输入和输出的组件之间的工作流如下所示:

    通量

返回页首

  1. 什么是 Redux?

    Redux 是基于 Flux 设计模式的 JavaScript 应用程序的可预测状态容器。Redux 可以与 React 一起使用,也可以与任何其他视图库一起使用。它很小(约2kB),没有依赖关系。

返回页首

  1. Redux的核心原则是什么?

    Redux遵循三个基本原则:

    1. 单一事实来源:整个应用程序的状态存储在单个存储区中的对象树中。通过单一状态树,可以更轻松地跟踪随时间推移的更改以及调试或检查应用程序。
    2. 状态是只读的:更改状态的唯一方法是发出一个动作,一个描述所发生情况的对象。这可确保视图和网络回调都不会直接写入状态。
    3. 更改是使用纯函数进行的:若要指定操作如何转换状态树,请编写化简器。化简器只是将上一个状态和一个动作作为参数,并返回下一个状态的纯函数。

返回页首

  1. 与Flux相比,Redux的缺点是什么?

    与其说缺点,我们可以说使用Redux而不是Flux几乎没有妥协。具体如下:

    1. 你将需要学会避免突变:Flux 对变异数据不以为然,但 Redux 不喜欢突变,许多补充 Redux 的包都假设你永远不会改变状态。你可以使用仅限开发的包(如 、不可变.js)或指示你的团队编写非可变代码来强制执行此操作。
      redux-immutable-state-invariant
    2. 你将不得不仔细挑选包裹:虽然 Flux 明确不尝试解决撤消/重做、持久性或表单等问题,但 Redux 具有中间件和存储增强器等扩展点,并且它催生了一个丰富的生态系统。
    3. 目前还没有很好的 Flow 集成:Flux目前允许你做非常令人印象深刻的静态类型检查,而Redux还不支持这些检查。

返回页首

  1. 和 有什么区别?
    mapStateToProps()
    mapDispatchToProps()

    mapStateToProps()
    是一个实用程序,可帮助你的组件获取更新状态(由其他一些组件更新):

    const mapStateToProps = (state) => {
      return {
        todos: getVisibleTodos(state.todos, state.visibilityFilter)
      }
    }

    mapDispatchToProps()
    是一个实用程序,它将帮助你的组件触发操作事件(调度可能导致应用程序状态更改的操作):

    const mapDispatchToProps = (dispatch) => {
      return {
        onTodoClick: (id) => {
          dispatch(toggleTodo(id))
        }
      }
    }

    建议始终对 使用“对象速记”形式。

    mapDispatchToProps

    Redux 将其包装在另一个看起来像 (...args) => dispatch(onTodoClick(...args)),并将该包装器函数作为道具传递给你的组件。

     const mapDispatchToProps = ({
       onTodoClick
     })

返回页首

  1. 我可以在化简器中调度操作吗?

    在化简器中调度操作是一种反模式。你的化简器应该没有副作用,只需消化操作有效负载并返回新的状态对象。在化简器中添加侦听器和调度操作可能会导致链接操作和其他副作用。

返回页首

  1. 如何在组件外部访问 Redux 存储?

    你只需要使用 从创建存储的模块中导出存储。此外,它不应该污染全局窗口对象。

    createStore()

    store = createStore(myReducer)
    
    export default store

返回页首

  1. MVW 模式的缺点是什么?

    1. DOM 操作非常昂贵,这会导致应用程序行为缓慢且效率低下。
    2. 由于循环依赖关系,围绕模型和视图创建了一个复杂的模型。
    3. 协作应用程序(如Google Docs)会发生大量数据更改。
    4. 没有办法在不添加这么多额外代码的情况下轻松撤消(时光倒流)。

返回页首

  1. Redux和RxJS之间有什么相似之处吗?

    这些库出于非常不同的目的而非常不同,但有一些模糊的相似之处。

    Redux 是一种用于管理整个应用程序状态的工具。它通常用作 UI 的体系结构。把它想象成(一半)Angular的替代品。RxJS是一个响应式编程库。它通常用作在JavaScript中完成异步任务的工具。把它看作是承诺的替代品。Redux 使用响应式范例,因为存储是响应式的。商店从远处观察操作,并改变自己。RxJS也使用响应式范式,但它不是架构,而是为你提供基本的构建块, Observable 量,以实现此模式。

返回页首

  1. 如何在加载时调度操作?

    可以在方法中调度操作,也可以在方法中验证数据。

    componentDidMount()
    render()

    class App extends Component {
      componentDidMount() {
        this.props.fetchData()
      }
    
      render() {
        return this.props.isLoaded
          ? <div>{'Loaded'}</div>
          : <div>{'Not Loaded'}</div>
      }
    }
    
    const mapStateToProps = (state) => ({
      isLoaded: state.isLoaded
    })
    
    const mapDispatchToProps = { fetchData }
    
    export default connect(mapStateToProps, mapDispatchToProps)(App)

返回页首

  1. 如何使用 React Redux?
    connect()

    你需要执行两个步骤才能在容器中使用商店:

    1. 使用 mapStateToProps():它将状态变量从你的商店映射到你指定的道具。

    2. 将上述道具连接到你的容器:函数返回的对象连接到容器。你可以从 导入。

      mapStateToProps
      connect()
      react-redux

      import React from 'react'
      import { connect } from 'react-redux'
      
      class App extends React.Component {
        render() {
          return <div>{this.props.containerData}</div>
        }
      }
      
      function mapStateToProps(state) {
        return { containerData: state.data }
      }
      
      export default connect(mapStateToProps)(App)

返回页首

  1. 如何在Redux中重置状态?

    你需要在应用程序中编写一个根化简器,它将处理操作委托给由 生成的化简器

    combineReducers()

    例如,让我们在操作后返回初始状态。众所周知,无论操作如何,当化简器作为第一个参数调用时,它们都应该返回初始状态。

    rootReducer()
    USER_LOGOUT
    undefined

    const appReducer = combineReducers({
      /* your app's top-level reducers */
    })
    
    const rootReducer = (state, action) => {
      if (action.type === 'USER_LOGOUT') {
        state = undefined
      }
    
      return appReducer(state, action)
    }

    如果使用 ,你可能还需要清理你的存储空间。 在存储引擎中保留状态的副本。首先,你需要导入相应的存储引擎,然后在将其设置为 undefined 之前解析状态并清理每个存储状态键。

    redux-persist
    redux-persist

    const appReducer = combineReducers({
      /* your app's top-level reducers */
    })
    
    const rootReducer = (state, action) => {
      if (action.type === 'USER_LOGOUT') {
        Object.keys(state).forEach(key => {
          storage.removeItem(`persist:${key}`)
        })
    
        state = undefined
      }
    
      return appReducer(state, action)
    }

返回页首

  1. Redux 连接装饰器中符号的用途是什么?
    at

    @ 符号实际上是一个用于表示装饰器的 JavaScript 表达式。通过修饰器,可以在设计时批注和修改类和属性。

    让我们举一个在没有装饰器和没有装饰器的情况下设置 Redux 的例子。

    • 不带装饰器:

      import React from 'react'
      import * as actionCreators from './actionCreators'
      import { bindActionCreators } from 'redux'
      import { connect } from 'react-redux'
      
      function mapStateToProps(state) {
        return { todos: state.todos }
      }
      
      function mapDispatchToProps(dispatch) {
        return { actions: bindActionCreators(actionCreators, dispatch) }
      }
      
      class MyApp extends React.Component {
        // ...define your main app here
      }
      
      export default connect(mapStateToProps, mapDispatchToProps)(MyApp)
    • 带装饰器:

      import React from 'react'
      import * as actionCreators from './actionCreators'
      import { bindActionCreators } from 'redux'
      import { connect } from 'react-redux'
      
      function mapStateToProps(state) {
        return { todos: state.todos }
      }
      
      function mapDispatchToProps(dispatch) {
        return { actions: bindActionCreators(actionCreators, dispatch) }
      }
      
      @connect(mapStateToProps, mapDispatchToProps)
      export default class MyApp extends React.Component {
        // ...define your main app here
      }

    上面的例子几乎相似,除了装饰器的用法。装饰器语法尚未内置到任何 JavaScript 运行时中,并且仍处于实验阶段,可能会发生变化。你可以使用 babel 作为装饰器支持。

返回页首

  1. React 上下文和 React Redux 有什么区别?

    你可以直接在应用程序中使用上下文,并且非常适合将数据传递到深度嵌套的组件,这是它的设计目的。

    Redux 功能强大得多,并且提供了大量上下文 API 不提供的功能。此外,React Redux 在内部使用上下文,但它不会在公共 API 中公开这一事实。

返回页首

  1. 为什么 Redux 状态函数被称为化简器?

    化简器始终返回状态的累积(基于所有先前和当前操作)。因此,它们充当了状态的还原器。每次调用 Redux 化简器时,状态和操作都会作为参数传递。然后根据操作减少(或累加)此状态,然后返回下一个状态。你可以减少操作的集合和(存储的)初始状态,对其执行这些操作以获取生成的最终状态。

返回页首

  1. 如何在 Redux 中发出 AJAX 请求?

    你可以使用中间件来定义异步操作。

    redux-thunk

    让我们举一个使用提取 API 将特定帐户作为 AJAX 调用提取的示例:

    export function fetchAccount(id) {
      return dispatch => {
        dispatch(setLoadingAccountState()) // Show a loading spinner
        fetch(`/account/${id}`, (response) => {
          dispatch(doneFetchingAccount()) // Hide loading spinner
          if (response.status === 200) {
            dispatch(setAccount(response.json)) // Use a normal function to set the received state
          } else {
            dispatch(someError)
          }
        })
      }
    }
    
    function setAccount(data) {
     return { type: 'SET_Account', data: data }
    }

返回页首

  1. 我应该将所有组件的状态保留在 Redux 存储中吗?

    将数据保留在 Redux 存储中,并将 UI 相关状态保留在组件内部。

返回页首

  1. 访问 Redux 存储的正确方法是什么?

    在组件中访问商店的最佳方法是使用该函数,该函数创建一个围绕现有组件的新组件。这种模式被称为高阶组件,通常是在 React 中扩展组件功能的首选方式。这允许你将状态和操作创建者映射到组件,并在商店更新时自动传入它们。

    connect()

    让我们以使用 connect 的组件为例:

    <FilterLink>

    import { connect } from 'react-redux'
    import { setVisibilityFilter } from '../actions'
    import Link from '../components/Link'
    
    const mapStateToProps = (state, ownProps) => ({
      active: ownProps.filter === state.visibilityFilter
    })
    
    const mapDispatchToProps = (dispatch, ownProps) => ({
      onClick: () => dispatch(setVisibilityFilter(ownProps.filter))
    })
    
    const FilterLink = connect(
      mapStateToProps,
      mapDispatchToProps
    )(Link)
    
    export default FilterLink

    由于它具有相当多的性能优化并且通常不太可能导致错误,因此Redux开发人员几乎总是建议使用直接访问商店(使用上下文API)。

    connect()

    class MyComponent {
      someMethod() {
        doSomethingWith(this.context.store)
      }
    }

返回页首

  1. React Redux 中的组件和容器有什么区别?

    组件是描述应用程序的表示部分的类或函数组件

    容器是连接到 Redux 存储的组件的非正式术语。容器订阅 Redux 状态更新和调度操作,它们通常不渲染 DOM 元素;它们将呈现委托给表示子组件。

返回页首

  1. Redux 中常量的目的是什么?

    使用常量,你可以在使用 IDE 时在整个项目中轻松找到该特定功能的所有用法。它还可以防止你引入由拼写错误引起的愚蠢错误——在这种情况下,你将立即得到一个。

    ReferenceError

    通常我们会将它们保存在单个文件( 或 )。

    constants.js
    actionTypes.js

    export const ADD_TODO = 'ADD_TODO'
    export const DELETE_TODO = 'DELETE_TODO'
    export const EDIT_TODO = 'EDIT_TODO'
    export const COMPLETE_TODO = 'COMPLETE_TODO'
    export const COMPLETE_ALL = 'COMPLETE_ALL'
    export const CLEAR_COMPLETED = 'CLEAR_COMPLETED'

    在 Redux 中,你可以在两个位置使用它们:

    1. 在操作创建期间:

      让我们采取:

      actions.js

      import { ADD_TODO } from './actionTypes';
      
      export function addTodo(text) {
        return { type: ADD_TODO, text }
      }
    2. 在减速机中:

      让我们创建:

      reducer.js

      import { ADD_TODO } from './actionTypes'
      
      export default (state = [], action) => {
        switch (action.type) {
          case ADD_TODO:
            return [
              ...state,
              {
                text: action.text,
                completed: false
              }
            ];
          default:
            return state
        }
      }

返回页首

  1. 有哪些不同的写作方式?
    mapDispatchToProps()

    有几种方法可以将动作创建者绑定到 中。

    dispatch()
    mapDispatchToProps()

    以下是可能的选项:

    const mapDispatchToProps = (dispatch) => ({
     action: () => dispatch(action())
    })
    const mapDispatchToProps = (dispatch) => ({
     action: bindActionCreators(action, dispatch)
    })
    const mapDispatchToProps = { action }

    第三个选项只是第一个选项的简写。

返回页首

  1. 和中的参数有什么用?
    ownProps
    mapStateToProps()
    mapDispatchToProps()

    如果指定了参数,React Redux 会将传递给组件的 props 传递给你的连接函数。因此,如果你使用连接的组件:

    ownProps

    import ConnectedComponent from './containers/ConnectedComponent';
    
    <ConnectedComponent user={'john'} />

    你的和函数内部将是一个对象:

    ownProps
    mapStateToProps()
    mapDispatchToProps()

    { user: 'john' }

    可以使用此对象来决定从这些函数返回的内容。

返回页首

  1. 如何构建 Redux 顶级目录?

    大多数应用程序都有几个顶级目录,如下所示:

    1. 组件:用于不知道 Redux 的哑组件
    2. 容器:用于连接到 Redux 的智能组件。
    3. 操作:用于所有操作创建者,其中文件名对应于应用的一部分。
    4. 化简器:用于所有化简器,其中文件名对应于状态键。
    5. 存储:用于存储初始化。

    此结构适用于中小型应用。

返回页首

  1. 什么是 redux-saga?

    redux-saga
    是一个库,旨在使 React/Redux 应用程序中的副作用(异步事情,如数据获取和不纯的东西,如访问浏览器缓存)更容易和更好。

    它在 NPM 中可用:

    $ npm install --save redux-saga

返回页首

  1. reux-saga的心智模型是什么?

    Saga 就像应用程序中的一个单独线程,它全权负责副作用。 是一个 Redux 中间件,这意味着这个线程可以通过正常的 Redux 操作从主应用程序中启动、暂停和取消,它可以访问完整的 Redux 应用程序状态,也可以调度 Redux 操作。

    redux-saga

返回页首

  1. 和 redux-saga 之间有什么区别?
    call()
    put()

    两者都是效果创建器函数。 函数用于创建效果描述,指示中间件调用 promise。 函数创建一个效果,指示中间件将操作调度到存储区。

    call()
    put()
    call()
    put()

    让我们举例说明这些效果如何用于获取特定用户数据。

    function* fetchUserSaga(action) {
      // `call` function accepts rest arguments, which will be passed to `api.fetchUser` function.
      // Instructing middleware to call promise, it resolved value will be assigned to `userData` variable
      const userData = yield call(api.fetchUser, action.userId)
    
      // Instructing middleware to dispatch corresponding action.
      yield put({
        type: 'FETCH_USER_SUCCESS',
        userData
      })
    }

返回页首

  1. 什么是 Redux Thunk?

    Redux Thunk 中间件允许你编写返回函数而不是操作的操作创建者。thunk 可用于延迟操作的调度,或仅在满足特定条件时才调度。内部函数接收存储方法和参数。

    dispatch()
    getState()

返回页首

  1. 和 之间有什么区别?
    redux-saga
    redux-thunk

    Redux ThunkRedux Saga都负责处理副作用。在大多数情况下,Thunk使用Promises来处理它们,而Saga使用生成器。Thunk使用简单,许多开发人员都熟悉Promises,Sagas/Generators功能更强大,但你需要学习它们。但是这两种中间件可以共存,因此你可以从Thunks开始,并在需要时引入Sagas。

返回页首

  1. 什么是 Redux DevTools?

    Redux DevTools 是 Redux 的实时编辑时间旅行环境,具有热重载、动作回放和可自定义的 UI。如果你不想费心安装 Redux DevTools 并将其集成到你的项目中,请考虑使用 Chrome 和 Firefox 的 Redux DevTools Extension。

返回页首

  1. Redux DevTools 有哪些功能?

    Redux DevTools 的一些主要功能如下:

    1. 允许你检查每个状态和操作有效负载。
    2. 允许你通过取消操作回到过去。
    3. 如果更改化简器代码,将重新评估每个暂存操作。
    4. 如果化简器抛出,你将看到这是在哪个操作期间发生的,以及错误是什么。
    5. 使用存储增强器,可以在页面重新加载期间保留调试会话。
      persistState()

返回页首

  1. 什么是 Redux 选择器,为什么要使用它们?

    选择器是将 Redux 状态作为参数并返回一些数据以传递给组件的函数。

    例如,要从状态获取用户详细信息,请执行以下操作:

    const getUserData = state => state.user.data

    这些选择器有两个主要优点,

    1. 选择器可以计算派生数据,允许 Redux 存储最小可能的状态
    2. 除非选择器的参数之一发生更改,否则不会重新计算选择器

返回页首

  1. 什么是 Redux Form?

    Redux Form 与 React 和 Redux 配合使用,使 React 中的表单能够使用 Redux 来存储其所有状态。Redux Form可以与原始HTML5输入一起使用,但它也可以很好地与常见的UI框架一起使用,如Material UI,React Widgets和React Bootstrap。

返回页首

  1. Redux Form的主要功能是什么?

    Redux Form的一些主要功能是:

    1. 通过 Redux 存储实现字段值持久性。
    2. 验证(同步/异步)和提交。
    3. 字段值的格式化、解析和规范化。

返回页首

  1. 如何在 Redux 中添加多个中间件?

    你可以使用 .

    applyMiddleware()

    例如,你可以将它们作为参数添加并传递给:

    redux-thunk
    logger
    applyMiddleware()

    import { createStore, applyMiddleware } from 'redux'
    const createStoreWithMiddleware = applyMiddleware(ReduxThunk, logger)(createStore)

返回页首

  1. 如何在 Redux 中设置初始状态?

    你需要将初始状态作为第二个参数传递给 createStore:

    const rootReducer = combineReducers({
      todos: todos,
      visibilityFilter: visibilityFilter
    })
    
    const initialState = {
      todos: [{ id: 123, name: 'example', completed: false }]
    }
    
    const store = createStore(
      rootReducer,
      initialState
    )

返回页首

  1. Relay 与 Redux 有何不同?

    Relay 与 Redux 类似,因为它们都使用单个存储。主要区别在于 relay 只管理源自服务器的状态,所有对状态的访问都通过 GraphQL 查询(用于读取数据)和突变(用于更改数据)使用。Relay 为你缓存数据并为你优化数据获取,仅获取更改的数据,仅提取其他数据。

  2. 什么是 Redux 中的操作?

    操作是普通的 JavaScript 对象或信息的有效负载,用于将数据从应用程序发送到你的商店。它们是商店的唯一信息来源。操作必须具有指示正在执行的操作类型的类型属性。

    例如,让我们执行一个表示添加新待办事项的操作:

    {
      type: ADD_TODO,
      text: 'Add todo item'
    }
    

返回页首

React 原生

返回页首

  1. React Native 和 React 有什么区别?

    React 是一个 JavaScript 库,支持前端 Web 并在服务器上运行,用于构建用户界面和 Web 应用程序。

    React Native 是一个编译为原生应用程序组件的移动框架,允许你在 JavaScript 中构建原生移动应用程序(iOS、Android 和 Windows),允许你使用 React 构建组件,并在后台实现 React。

返回页首

  1. 如何测试 React Native 应用程序?

    React Native 只能在 iOS 和 Android 等移动模拟器中进行测试。你可以使用世博会应用程序(https://expo.io)在手机中运行该应用程序,如果它使用QR码同步,则你的手机和计算机应位于同一无线网络中。

返回页首

  1. 如何在 React Native 中进行日志记录?

    你可以使用 、 等。从 React Native v0.29 开始,你只需运行以下命令即可在控制台中查看日志:

    console.log
    console.warn

    $ react-native log-ios
    $ react-native log-android
    

返回页首

  1. 如何调试你的 React Native?

    按照以下步骤调试 React Native 应用程序:

    1. 在 iOS 模拟器中运行应用程序。
    2. 按和网页应在 打开。
      Command + D
      http://localhost:8081/debugger-ui
    3. 启用“捕获异常时暂停”以获得更好的调试体验。
    4. 按下以打开 Chrome 开发者工具,或通过 -> -> 打开它。
      Command + Option + I
      View
      Developer
      Developer Tools
    5. 你现在应该能够像往常一样进行调试。

React 支持的库和集成

返回页首

  1. 什么是重新选择及其工作原理?

    Reselect是一个使用记忆概念的选择器库(用于Redux)。它最初是为了计算来自类似 Redux 的应用程序状态的派生数据而编写的,但它不能绑定到任何体系结构或库。

    重新选择保留上次调用的上次输入/输出的副本,并且仅在其中一个输入更改时才重新计算结果。如果连续两次提供相同的输入,则“重新选择”将返回缓存的输出。它的记忆和缓存是完全可定制的。

返回页首

  1. 什么是心流?

    Flow 是一个静态类型检查器,旨在查找 JavaScript 中的类型错误。与传统类型系统相比,流动类型可以表达更细粒度的区别。例如,Flow 可帮助你捕获涉及 的错误,这与大多数类型系统不同。

    null

返回页首

  1. 流和属性类型有什么区别?

    Flow 是一个静态分析工具(静态检查器),它使用语言的超集,允许你向所有代码添加类型注释,并在编译时捕获整类错误。

    PropType 是一个基本的类型检查器(运行时检查器),它已经修补到 React 上。除了传递给给定组件的 props 类型之外,它无法检查任何其他内容。如果你想对整个项目进行更灵活的类型检查,Flow/TypeScript 是合适的选择。

返回页首

  1. 如何在 React 中使用字体 awesome 图标?

    以下步骤在 React 中包含 Font Awesome:

    1. 安装:

      font-awesome

      $ npm install --save font-awesome
    2. 在文件中导入:

      font-awesome
      index.js

      import 'font-awesome/css/font-awesome.min.css'
    3. 在以下位置添加字体 awesome 类:

      className

      render() {
        return <div><i className={'fa fa-spinner'} /></div>
      }

返回页首

  1. 什么是 React Dev Tools?

    React 开发人员工具允许你检查组件层次结构,包括组件属性和状态。它既可以作为浏览器扩展(适用于Chrome和Firefox)存在,也可以作为独立应用程序(适用于其他环境,包括Safari,IE和React Native)存在。

    适用于不同浏览器或环境的官方扩展。

    1. 铬扩展程序
    2. 火狐扩展
    3. 独立应用程序(Safari,React Native等)

返回页首

  1. 为什么 DevTools 没有在 Chrome 中加载本地文件?

    如果你在浏览器中打开了本地 HTML 文件(),则必须先打开 Chrome 扩展程序并检查 。

    file://...
    Allow access to file URLs

返回页首

  1. 如何在 React 中使用聚合物?

    你需要按照以下步骤在 React 中使用 Polymer,

    1. 创建聚合物元素:

      <link rel='import' href='../../bower_components/polymer/polymer.html' />
      Polymer({
        is: 'calender-element',
        ready: function() {
          this.textContent = 'I am a calender'
        }
      })
    2. 通过将 Polymer 组件 HTML 标签导入到 HTML 文档中来创建它,例如将其导入 React 应用程序:

      index.html

      <link rel='import' href='./src/polymer-components/calender-element.html'>
    3. 在 JSX 文件中使用该元素:

      import React from 'react'
      
      class MyComponent extends React.Component {
        render() {
          return (
            <calender-element />
          )
        }
      }
      
      export default MyComponent

返回页首

  1. React 相对于 Vue.js 有什么优势?

    与 Vue.js相比,React 具有以下优势:

    1. 为大型应用程序开发提供更大的灵活性。
    2. 更易于测试。
    3. 适合移动应用程序创建。
    4. 更多信息和解决方案可用。

注意:上述优势列表纯粹是固执己见,根据专业经验而有所不同。但它们作为基本参数很有用。

返回页首

  1. React 和 Angular 有什么区别?

    让我们看看表格格式的 React 和 Angular 之间的区别。

    React
    React 是一个库,只有视图层 Angular是一个框架,具有完整的MVC功能
    React 处理服务器端的渲染 AngularJS仅在客户端渲染,但Angular 2及更高版本在服务器端渲染
    React使用JSX,看起来像JS中的HTML,这可能会令人困惑 Angular 遵循 HTML 的模板方法,这使得代码更短且易于理解
    React Native,这是一种用于构建移动应用程序的React类型,更快,更稳定 Ionic,Angular的移动原生应用程序相对不太稳定且速度较慢
    在 React 中,数据仅以一种方式流动,因此调试很容易 在 Angular 中,数据是双向流动的,即它在子项和父项之间具有双向数据绑定,因此调试通常很困难

注意:上述差异列表纯粹是固执己见,根据专业经验而有所不同。但它们作为基本参数很有用。

返回页首

  1. 为什么 React 选项卡没有显示在 DevTools 中?

    当页面加载时,React DevTools 会设置一个名为 的全局,然后 React 在初始化期间与该钩子通信。如果网站没有使用 React 或者 React 无法与 DevTools 通信,那么它就不会显示该选项卡。

    __REACT_DEVTOOLS_GLOBAL_HOOK__

返回页首

  1. 什么是样式化组件?

    styled-components
    是一个用于样式化 React 应用程序的 JavaScript 库。它删除了样式和组件之间的映射,并允许你编写使用 JavaScript 增强的实际 CSS。

返回页首

  1. 举一个样式化组件的示例?

    让我们为每个组件创建和具有特定样式的组件。

    <Title>
    <Wrapper>

    import React from 'react'
    import styled from 'styled-components'
    
    // Create a <Title> component that renders an <h1> which is centered, red and sized at 1.5em
    const Title = styled.h1`
      font-size: 1.5em;
      text-align: center;
      color: palevioletred;
    `
    
    // Create a <Wrapper> component that renders a <section> with some padding and a papayawhip background
    const Wrapper = styled.section`
      padding: 4em;
      background: papayawhip;
    `

    这两个变量和 现在是可以像任何其他 react 组件一样渲染的组件。

    Title
    Wrapper

    <Wrapper>
      <Title>{'Lets start first styled component!'}</Title>
    </Wrapper>

返回页首

  1. 什么是中继?

    Relay 是一个 JavaScript 框架,用于使用 React 视图层为 Web 应用程序提供数据层和客户端-服务器通信。

返回页首

  1. 如何在应用程序中使用TypeScript?
    create-react-app

    从 react-scripts@2.1.0 或更高版本开始,对打字稿有内置支持。即,现在本机支持打字稿。你可以按如下方式传递选项

    create-react-app
    --typescript

    npx create-react-app my-app --typescript
    
    # or
    
    yarn create react-app my-app --typescript

    但是对于较低版本的 react 脚本,只需在创建新项目时提供选项即可。 是一组调整,用于采用标准项目管道并将 TypeScript 引入组合。

    --scripts-version
    react-scripts-ts
    react-scripts-ts
    create-react-app

    现在,项目布局应如下所示:

    my-app/
    ├─ .gitignore
    ├─ images.d.ts
    ├─ node_modules/
    ├─ public/
    ├─ src/
    │  └─ ...
    ├─ package.json
    ├─ tsconfig.json
    ├─ tsconfig.prod.json
    ├─ tsconfig.test.json
    └─ tslint.json
    

杂项

返回页首

  1. 重新选择库的主要功能是什么?

    让我们看看重新选择库的主要功能,

    1. 选择器可以计算派生数据,允许 Redux 存储尽可能小的状态。
    2. 选择器是高效的。除非选择器的参数之一发生更改,否则不会重新计算选择器。
    3. 选择器是可组合的。它们可以用作其他选择器的输入。
  2. 举一个重新选择用法的例子?

    让我们通过简化的 Reselect 用法计算货件订单的不同数量:

    import { createSelector } from 'reselect'
    
    const shopItemsSelector = state => state.shop.items
    const taxPercentSelector = state => state.shop.taxPercent
    
    const subtotalSelector = createSelector(
      shopItemsSelector,
      items => items.reduce((acc, item) => acc + item.value, 0)
    )
    
    const taxSelector = createSelector(
      subtotalSelector,
      taxPercentSelector,
      (subtotal, taxPercent) => subtotal * (taxPercent / 100)
    )
    
    export const totalSelector = createSelector(
      subtotalSelector,
      taxSelector,
      (subtotal, tax) => ({ total: subtotal + tax })
    )
    
    let exampleState = {
      shop: {
        taxPercent: 8,
        items: [
          { name: 'apple', value: 1.20 },
          { name: 'orange', value: 0.95 },
        ]
      }
    }
    
    console.log(subtotalSelector(exampleState)) // 2.15
    console.log(taxSelector(exampleState))      // 0.172
    console.log(totalSelector(exampleState))    // { total: 2.322 }

返回页首

  1. 静态对象是否适用于 React 中的 ES6 类?

    否,仅适用于:

    statics
    React.createClass()

    someComponent= React.createClass({
      statics: {
        someMethod: function() {
          // ..
        }
      }
    })

    但是你可以在 ES6+ 类中编写静态,如下所示:

    class Component extends React.Component {
      static propTypes = {
        // ...
      }
    
      static someMethod() {
        // ...
      }
    }

    或在课外写如下,

    class Component extends React.Component {
       ....
    }
    
    Component.propTypes = {...}
    Component.someMethod = function(){....}

返回页首

  1. Redux 只能与 React 一起使用吗?

    Redux 可以用作任何 UI 层的数据存储。最常见的用法是 React 和 React Native,但也有可用于 Angular、Angular 2、Vue、Mithril 等的绑定。Redux 只是提供了一种订阅机制,可供任何其他代码使用。

返回页首

  1. 你是否需要特定的构建工具来使用 Redux?

    Redux 最初是用 ES6 编写的,后来使用 Webpack 和 Babel 转译为 ES5。无论你的 JavaScript 构建过程如何,你都应该能够使用它。Redux 还提供了一个 UMD 构建,可以直接使用,而无需任何构建过程。

返回页首

  1. Redux表单如何从状态更新?
    initialValues

    你需要添加设置。

    enableReinitialize : true

    const InitializeFromStateForm = reduxForm({
      form: 'initializeFromState',
      enableReinitialize : true
    })(UserEdit)

    如果你的道具更新,你的表单也会更新。

    initialValues

返回页首

  1. React PropType 如何允许一个道具使用不同类型的道具?

    你可以使用 的方法。

    oneOfType()
    PropTypes

    例如,可以使用 或 类型定义 height 属性,如下所示:

    string
    number

    Component.propTypes = {
      size: PropTypes.oneOfType([
        PropTypes.string,
        PropTypes.number
      ])
    }

返回页首

  1. 我可以导入 SVG 文件作为 React 组件吗?

    你可以直接将 SVG 作为组件导入,而不是将其作为文件加载。此功能适用于及更高版本。

    react-scripts@2.0.0

    import { ReactComponent as Logo } from './logo.svg'
    
    const App = () => (
      <div>
        {/* Logo is an actual react component */}
        <Logo />
      </div>
    )

    注意:不要忘记导入中的大括号。

返回页首

  1. 为什么不建议使用内联引用回调或函数?

    如果 ref 回调被定义为内联函数,它将在更新期间被调用两次,首先使用 null,然后使用 DOM 元素。这是因为每次渲染都会创建一个函数的新实例,因此 React 需要清除旧的 ref 并设置新的 ref。

    class UserForm extends Component {
      handleSubmit = () => {
        console.log("Input Value is: ", this.input.value)
      }
    
    
      render () {
       return (
         <form onSubmit={this.handleSubmit}>
           <input
             type='text'
             ref={(input) => this.input = input} /> // Access DOM input in handle submit
           <button type='submit'>Submit</button>
         </form>
       )
     }
    }

    但我们的期望是在组件挂载时调用一次 ref 回调。一种快速解决方法是使用 ES7 类属性语法来定义函数

    class UserForm extends Component {
     handleSubmit = () => {
       console.log("Input Value is: ", this.input.value)
     }
    
     setSearchInput = (input) => {
       this.input = input
     }
    
     render () {
       return (
         <form onSubmit={this.handleSubmit}>
           <input
             type='text'
             ref={this.setSearchInput} /> // Access DOM input in handle submit
           <button type='submit'>Submit</button>
         </form>
       )
     }
    }
**Note:** In React v16.3,

返回页首

  1. 什么是 React 中的渲染劫持?

    渲染劫持的概念是控制一个组件将从另一个组件输出的内容的能力。这意味着你可以通过将组件包装到高阶组件中来装饰组件。通过包装,你可以注入其他道具或进行其他更改,这可能会导致渲染逻辑发生变化。它实际上并不启用劫持,但通过使用 HOC 可以使组件的行为不同。

返回页首

  1. 什么是 HOC 工厂实施?

    在 React 中实现 HOC 有两种主要方法。

    1. 道具代理 (PP) 和
    2. 继承倒置(二).

    但是它们遵循不同的方法来操作包装组件

    道具代理

    在这种方法中,HOC 的呈现方法返回一个包装组件类型的 React 元素。我们还通过 HOC 接收的道具,因此得名道具代理

    function ppHOC(WrappedComponent) {
     return class PP extends React.Component {
       render() {
         return <WrappedComponent {...this.props}/>
       }
     }
    }

    继承反转

    在此方法中,返回的 HOC 类(增强器)扩展了包装组件。它被称为继承反转,因为它不是 WrappedComponent 扩展某个增强器类,而是由增强器被动扩展。这样看来,它们之间的关系是相反的。

    function iiHOC(WrappedComponent) {
     return class Enhancer extends WrappedComponent {
       render() {
         return super.render()
       }
     }
    }

返回页首

  1. 如何将数字传递给 React 组件?

    你应该通过大括号 ({}) 传递数字,其中作为引号中的字符串

       React.render(<User age={30} department={"IT"} />, document.getElementById('container'));

返回页首

  1. 我是否需要将所有状态保留到 Redux 中?我应该使用 React 内部状态吗?

    这取决于开发人员的决定,即开发人员的工作是确定哪种状态构成你的应用程序,以及每个状态应该位于何处。一些用户更喜欢将每一条数据都保存在 Redux 中,以便始终维护其应用程序的完全可序列化和受控版本。其他人更喜欢将非关键或 UI 状态(例如“此下拉列表当前是否打开”)保留在组件的内部状态中。

    以下是确定应将哪种数据放入 Redux 的经验法则

    1. 应用程序的其他部分是否关心此数据?
    2. 你是否需要能够基于这些原始数据创建更多派生数据?
    3. 是否使用相同的数据来驱动多个组件?
    4. 能够将此状态还原到给定时间点(即时间旅行调试)对你有价值吗?
    5. 你是否要缓存数据(即,如果状态已经存在,则使用状态,而不是重新请求它)?

返回页首

  1. 在 React 中注册服务工作者的目的是什么?

    默认情况下,React 会为你创建一个服务工作线程,无需任何配置。服务工作者是一个 Web API,可帮助你缓存资产和其他文件,以便当用户离线或在慢速网络上时,他/她仍然可以在屏幕上看到结果,因此,它可以帮助你构建更好的用户体验,这就是你现在应该了解的关于服务工作者的信息。这一切都是为了向你的网站添加离线功能。

       import React from 'react';
       import ReactDOM from 'react-dom';
       import App from './App';
       import registerServiceWorker from './registerServiceWorker';
    
       ReactDOM.render(<App />, document.getElementById('root'));
       registerServiceWorker();

返回页首

  1. 什么是 React 备忘录功能?

    当类组件的输入属性相同时,可以使用 PureComponent 或 shouldComponentUpdate 来限制类组件重新渲染。现在,你可以通过将函数组件包装在 React.memo 中来对它们执行相同的操作。

    const MyComponent = React.memo(function MyComponent(props) {
     /* only rerenders if props change */
    });

返回页首

  1. 什么是 React 惰性函数?

    该函数允许你将动态导入呈现为常规组件。当组件被渲染时,它将自动加载包含 的捆绑包。这必须返回一个 Promise,该 Promise 解析为具有包含 React 组件的默认导出的模块。
    React.lazy
    OtherComponent
    const OtherComponent = React.lazy(() => import('./OtherComponent'));
    
    function MyComponent() {
     return (
       <div>
         <OtherComponent />
       </div>
     );
    }
    注意:并且尚不可用于服务器端渲染。如果你想在服务器渲染的应用程序中进行代码拆分,我们仍然建议使用 React Loadable。
    React.lazy
    Suspense

返回页首

  1. 如何使用 setState 防止不必要的更新?

    你可以将状态的当前值与现有状态值进行比较,并决定是否重新呈现页面。如果值相同,则需要返回 null 以停止重新渲染,否则返回最新的状态值。

    例如,用户配置文件信息有条件地呈现如下,

    getUserProfile = user => {
      const latestAddress = user.address;
      this.setState(state => {
        if (state.address === latestAddress) {
          return null;
        } else {
          return { title: latestAddress };
        }
      });
    };

返回页首

  1. 如何在 React 16 版本中渲染数组、字符串和数字?

    数组:与旧版本不同,你不需要确保渲染方法在 React16 中返回单个元素。你可以通过返回数组来返回多个没有包装元素的同级元素。

    例如,让我们以下面的开发人员列表为例,

    const ReactJSDevs = () => {
      return [
        <li key="1">John</li>,
        <li key="2">Jackie</li>,
        <li key="3">Jordan</li>
      ];
    }

    你还可以将此项目数组合并到另一个数组组件中。

    const JSDevs = () => {
      return (
        <ul>
          <li>Brad</li>
          <li>Brodge</li>
          <ReactJSDevs/>
          <li>Brandon</li>
        </ul>
      );
    }

    字符串和数字:还可以从 render 方法返回字符串和数字类型。

    render() {
     return 'Welcome to ReactJS questions';
    }
    // Number
    render() {
     return 2018;
    }

返回页首

  1. 如何在 React 类中使用类字段声明语法?

    React 类组件可以使用类字段声明变得更加简洁。可以在不使用构造函数的情况下初始化本地状态,并使用箭头函数声明类方法,而无需绑定它们。

    让我们举一个反例来演示不使用构造函数和不绑定的方法的状态的类字段声明,

    class Counter extends Component {
      state = { value: 0 };
    
      handleIncrement = () => {
        this.setState(prevState => ({
          value: prevState.value + 1
        }));
      };
    
      handleDecrement = () => {
        this.setState(prevState => ({
          value: prevState.value - 1
        }));
      };
    
      render() {
        return (
          <div>
            {this.state.value}
    
            <button onClick={this.handleIncrement}>+</button>
            <button onClick={this.handleDecrement}>-</button>
          </div>
        )
      }
    }

返回页首

  1. 什么是钩子?

    Hooks 是一个特殊的函数(在 React 16.8 中作为新功能引入),它允许你在不编写类的情况下使用状态和其他 React 功能。

    让我们看一个useState钩子的例子:

    import { useState } from 'react';
    
    function Example() {
      // Declare a new state variable, which we'll call "count"
      const [count, setCount] = useState(0);
    
      return (
        <div>
          <p>You clicked {count} times</p>
          <button onClick={() => setCount(count + 1)}>
            Click me
          </button>
        </div>
      );
    }

    注意:钩子可以在现有函数组件中使用。

返回页首

  1. 钩子需要遵循哪些规则?

    你需要遵循两个规则才能使用钩子,

    1. 仅在 react 函数的顶层调用 Hooks。也就是说,你不应该在循环、条件或嵌套函数中调用 Hooks。这将确保每次组件呈现时都以相同的顺序调用 Hook,并在多个 useState 和 useEffect 调用之间保留 Hook 的状态。
    2. 仅从 React 函数调用钩子。也就是说,你不应该从常规的JavaScript函数调用Hooks。

返回页首

  1. 如何确保钩子遵循项目中的规则?

    React 团队发布了一个名为 eslint-plugin-react-hooks 的 ESLint 插件,它强制执行这两个规则。你可以使用以下命令将此插件添加到你的项目中,
    npm install eslint-plugin-react-hooks@next
    并在 ESLint 配置文件中应用以下配置,
    // Your ESLint configuration
    {
      "plugins": [
        // ...
        "react-hooks"
      ],
      "rules": {
        // ...
        "react-hooks/rules-of-hooks": "error"
      }
    }
    注意:默认情况下,此插件旨在用于创建 React 应用程序。

返回页首

  1. Flux 和 Redux 有什么区别?

    以下是 Flux 和 Redux 之间的主要区别

    通量 雷杜克斯
    状态是可变的 状态是不可变的
    应用商店包含状态和更改逻辑 存储和更改逻辑是分开的
    存在多个商店 只有一家商店存在
    所有商店都是断开和扁平的 带分层缩减器的单一商店
    它有一个单例调度程序 没有调度程序的概念
    React 组件订阅商店 容器组件使用连接功能

返回页首

  1. React Router V4有什么好处?

    以下是 React Router V4 模块的主要优点,

    1. 在 React Router v4(版本 4)中,API 完全是关于组件的。路由器可以可视化为包装特定子路由器组件()的单个组件()。
      <BrowserRouter>
      <Route>
    2. 你无需手动设置历史记录。路由器模块将通过用组件包装路由来处理历史记录。
      <BrowserRouter>
    3. 通过仅添加特定的路由器模块(Web、核心或本机)来减小应用程序大小

返回页首

  1. 你能描述一下 componentDidCatch 生命周期方法签名吗?

    组件 DidCatch 生命周期方法在后代组件引发错误后调用。该方法接收两个参数,

    1. 错误: - 抛出的错误对象
    2. 信息: - 具有组件堆栈键的对象包含有关哪个组件引发错误的信息。

    方法结构如下

    componentDidCatch(error, info)

返回页首

  1. 在哪些情况下,错误边界不会捕获错误?

    以下是错误边界不起作用的情况,

    1. 内部事件处理程序
    2. 使用 setTimeout 或 requestAnimationFrame 回调的异步代码
    3. 在服务器端呈现期间
    4. 当错误边界代码本身抛出错误时

返回页首

  1. 为什么事件处理程序不需要错误边界?

    错误边界不会捕获事件处理程序中的错误。

    React 不需要错误边界来从事件处理程序中的错误中恢复。与呈现方法和生命周期方法不同,事件处理程序在呈现期间不会发生。因此,如果他们抛出,React 仍然知道在屏幕上显示什么。

    如果需要在事件处理程序中捕获错误,请使用常规的 JavaScript try / catch 语句:

    class MyComponent extends React.Component {
      constructor(props) {
        super(props);
        this.state = { error: null };
        this.handleClick = this.handleClick.bind(this);
      }
    
      handleClick() {
        try {
          // Do something that could throw
        } catch (error) {
          this.setState({ error });
        }
      }
    
      render() {
        if (this.state.error) {
          return <h1>Caught an error.</h1>
        }
        return <button onClick={this.handleClick}>Click Me</button>
      }
    }

    请注意,上面的示例演示了常规的 JavaScript 行为,并且不使用错误边界。

返回页首

  1. 尝试捕获块和错误边界有什么区别?

    尝试 catch 块适用于命令性代码,而错误边界用于在屏幕上呈现的声明性代码。

    例如,用于以下命令式代码的 try catch 块

    try {
      showButton();
    } catch (error) {
      // ...
    }

    虽然错误边界包装声明性代码,如下所示,

    <ErrorBoundary>
      <MyComponent />
    </ErrorBoundary>

    因此,如果 componentDidUpdate 方法中发生错误,由树中某处的 setState 引起,它仍将正确传播到最近的错误边界。

返回页首

  1. React 16 中未捕获错误的行为是什么?

    在 React 16 中,未被任何错误边界捕获的错误将导致卸载整个 React 组件树。此决定背后的原因是,保留损坏的 UI 比完全删除它更糟糕。例如,对于支付应用来说,显示错误的金额比不显示任何金额更糟糕。

返回页首

  1. 错误边界的正确位置是什么?

    错误边界使用的粒度由开发人员根据项目需求决定。你可以遵循以下任一方法,
    1. 你可以包装顶级路由组件以显示整个应用程序的通用错误消息。
    2. 你还可以将各个组件包装在错误边界中,以防止它们使应用程序的其余部分崩溃。

返回页首

  1. 从错误边界跟踪组件堆栈有什么好处?

    除了错误消息和 javascript 堆栈之外,React16 还将使用错误边界概念显示带有文件名和行号的组件堆栈跟踪。

    例如,BuggyCounter 组件显示组件堆栈跟踪,如下所示,

    堆栈跟踪

返回页首

  1. 为类组件定义所需的方法是什么?

    该方法是类组件中唯一必需的方法。即,除 render 方法以外的所有方法对于类组件都是可选的。
    render()

返回页首

  1. 渲染方法的可能返回类型有哪些?

    以下是以下使用和从渲染方法返回的类型列表,

    1. React 元素:指示 React 渲染 DOM 节点的元素。它包括html元素,如和用户定义的元素。
      <div/>
    2. 数组和片段:返回多个元素以呈现为数组和片段以包装多个元素
    3. 门户:将子级呈现到不同的 DOM 子树中。
    4. 字符串和数字:在 DOM 中将字符串和数字呈现为文本节点
    5. 布尔值或空值:不呈现任何内容,但这些类型用于有条件地呈现内容。

返回页首

  1. 构造函数的主要目的是什么?

    构造函数主要用于两个目的,

    1. 通过将对象分配给 this.state 来初始化本地状态
    2. 用于将事件处理程序方法绑定到实例 例如,下面的代码涵盖了上述两种情况,
    constructor(props) {
      super(props);
      // Don't call this.setState() here!
      this.state = { counter: 0 };
      this.handleClick = this.handleClick.bind(this);
    }

返回页首

  1. 是否必须为 React 组件定义构造函数?

    不,这不是强制性的。即,如果你不初始化状态并且不绑定方法,则不需要为 React 组件实现构造函数。

返回页首

  1. 什么是默认道具?

    defaultProps 被定义为组件类上的一个属性,用于设置该类的默认 props。这用于未定义的道具,但不用于空道具。

    例如,让我们为按钮组件创建颜色默认道具,

    class MyButton extends React.Component {
      // ...
    }
    
    MyButton.defaultProps = {
      color: 'red'
    };

    如果未提供,则它将默认值设置为“红色”。即,每当你尝试访问颜色道具时,它都会使用默认值

    props.color

    render() {
       return <MyButton /> ; // props.color will be set to red
     }

    注意:如果提供空值,则它仍然是空值。

返回页首

  1. 为什么不应该在组件中调用 setStateWillUnmount?

    你不应调用,因为一旦卸载组件实例,它将永远不会再次挂载。
    setState()
    componentWillUnmount()

返回页首

  1. getDerivedStateFromError的目的是什么?

    此生命周期方法在后代组件引发错误后调用。它接收作为参数引发的错误,并应返回一个值以更新状态。

    生命周期方法的签名如下:

    static getDerivedStateFromError(error)

    让我们以上述生命周期方法的错误边界用例为例进行演示,

    class ErrorBoundary extends React.Component {
      constructor(props) {
        super(props);
        this.state = { hasError: false };
      }
    
      static getDerivedStateFromError(error) {
        // Update state so the next render will show the fallback UI.
        return { hasError: true };
      }
    
      render() {
        if (this.state.hasError) {
          // You can render any custom fallback UI
          return <h1>Something went wrong.</h1>;
        }
    
        return this.props.children;
      }
    }

返回页首

  1. 重新渲染组件时的方法顺序是什么?

    更新可能是由对道具或状态的更改引起的。重新呈现组件时,将按以下顺序调用以下方法。

    1. static getDerivedStateFromProps()
    2. 应该组件更新()
    3. 渲染()
    4. getSnapshotBeforeUpdate()
    5. componentDidUpdate()

返回页首

  1. 在错误处理期间调用了哪些方法?

    当呈现期间、生命周期方法或任何子组件的构造函数中出现错误时,将调用以下方法。

    1. static getDerivedStateFromError()
    2. componentDidCatch()

返回页首

  1. 显示名称类属性的用途是什么?

    显示名称字符串用于调试消息。通常,不需要显式设置它,因为它是从定义组件的函数或类的名称推断出来的。如果要显示其他名称以进行调试或在创建高阶组件时,可能需要显式设置它。

    例如,为了便于调试,请选择一个显示名称,以传达它是订阅 HOC 的结果。

    function withSubscription(WrappedComponent) {
      class WithSubscription extends React.Component {/* ... */}
      WithSubscription.displayName = `WithSubscription(${getDisplayName(WrappedComponent)})`;
      return WithSubscription;
    }
    function getDisplayName(WrappedComponent) {
      return WrappedComponent.displayName || WrappedComponent.name || 'Component';
    }

返回页首

  1. 浏览器对 React 应用程序的支持是什么?

    React 支持所有流行的浏览器,包括 Internet Explorer 9 及更高版本,尽管 IE 9 和 IE 10 等旧版浏览器需要一些 polyfill。如果你使用 es5-shim 和 es5-sham polyfill,那么它甚至支持不支持 ES5 方法的旧浏览器。

返回页首

  1. unmountComponentAtNode方法的目的是什么?

    此方法可从 react-dom 包中获得,它从 DOM 中删除一个挂载的 React 组件并清理其事件处理程序和状态。如果容器中未装载任何组件,则调用此函数不执行任何操作。如果组件已卸载,则返回 true;如果没有要卸载的组件,则返回 false。

    方法签名如下所示,

    ReactDOM.unmountComponentAtNode(container)

返回页首

  1. 什么是代码拆分?

    代码拆分是Webpack和Browserify等捆绑器支持的功能,它可以创建多个可以在运行时动态加载的捆绑包。react 项目支持通过动态 import() 功能进行代码拆分。

    例如,在下面的代码片段中,它将使 moduleA.js 及其所有唯一依赖项作为一个单独的块,仅在用户单击“加载”按钮后加载。模块 A.js

    const moduleA = 'Hello';
    
    export { moduleA };

    应用.js

    import React, { Component } from 'react';
    
    class App extends Component {
      handleClick = () => {
        import('./moduleA')
          .then(({ moduleA }) => {
            // Use moduleA
          })
          .catch(err => {
            // Handle failure
          });
      };
    
      render() {
        return (
          <div>
            <button onClick={this.handleClick}>Load</button>
          </div>
        );
      }
    }
    
    export default App;

返回页首

  1. 严格模式有什么好处?

    在以下情况下会有所帮助

    1. 识别具有不安全生命周期方法的组件。
    2. 有关旧字符串引用 API 用法的警告。
    3. 检测意外的副作用
    4. 检测旧版上下文 API。
    5. 有关已弃用的 findDOMNode 用法的警告

返回页首

  1. 什么是键控片段?

    使用显式<React.Fragment>语法声明的片段可能有键。一般用例是将集合映射到片段数组,如下所示,

    function Glossary(props) {
      return (
        <dl>
          {props.items.map(item => (
            // Without the `key`, React will fire a key warning
            <React.Fragment key={item.id}>
              <dt>{item.term}</dt>
              <dd>{item.description}</dd>
            </React.Fragment>
          ))}
        </dl>
      );
    }

    注意:key 是唯一可以传递给片段的属性。将来,可能会支持其他属性,例如事件处理程序。

返回页首

  1. React 是否支持所有 HTML 属性?

    从 React 16 开始,标准或自定义 DOM 属性都完全受支持。由于 React 组件通常同时采用自定义和与 DOM 相关的 props,因此 React 像 DOM API 一样使用 camelCase 约定。

    让我们对标准 HTML 属性采取一些道具,

    <div tabIndex="-1" />      // Just like node.tabIndex DOM API
    <div className="Button" /> // Just like node.className DOM API
    <input readOnly={true} />  // Just like node.readOnly DOM API

    这些 props 的工作方式与相应的 HTML 属性类似,但特殊情况除外。它还支持所有 SVG 属性。

返回页首

  1. HOC 有哪些限制?

    除了优点之外,高阶组件还有一些注意事项。以下是按顺序列出的几个,

    1. 不要在呈现方法中使用 HOC:不建议将 HOC 应用于组件的呈现方法中的组件。

      render() {
        // A new version of EnhancedComponent is created on every render
        // EnhancedComponent1 !== EnhancedComponent2
        const EnhancedComponent = enhance(MyComponent);
        // That causes the entire subtree to unmount/remount each time!
        return <EnhancedComponent />;
      }

      上面的代码通过重新装载组件来影响性能,该组件会导致该组件及其所有子组件的状态丢失。相反,请在组件定义之外应用 HOC,以便仅创建一次生成的组件。

    2. 静态方法必须复制到:将 HOC 应用于组件时,新组件不具有原始组件的任何静态方法

      // Define a static method
      WrappedComponent.staticMethod = function() {/*...*/}
      // Now apply a HOC
      const EnhancedComponent = enhance(WrappedComponent);
      
      // The enhanced component has no static method
      typeof EnhancedComponent.staticMethod === 'undefined' // true

      你可以通过在返回容器之前将方法复制到容器上来解决此问题,

      function enhance(WrappedComponent) {
        class Enhance extends React.Component {/*...*/}
        // Must know exactly which method(s) to copy :(
        Enhance.staticMethod = WrappedComponent.staticMethod;
        return Enhance;
      }
    3. 引用不会传递:对于 HOC,你需要将所有道具传递到包装的组件,但这不适用于 refs。这是因为 ref 并不是真正类似于键的道具。在这种情况下,你需要使用 React.forwardRef API

返回页首

  1. 如何在 DevTools 中调试 forwardRefs?

    React.forwardRef 接受渲染函数作为参数,DevTools 使用此函数来确定要为 ref 转发组件显示的内容。

    例如,如果不命名渲染函数或不使用 displayName 属性,则它将在 DevTools 中显示为“ForwardRef”,

    const WrappedComponent = React.forwardRef((props, ref) => {
      return <LogProps {...props} forwardedRef={ref} />;
    });

    但是如果你命名渲染函数,那么它将显示为“ForwardRef(myFunction)”

    const WrappedComponent = React.forwardRef(
      function myFunction(props, ref) {
        return <LogProps {...props} forwardedRef={ref} />;
      }
    );

    作为替代方法,你还可以为 forwardRef 函数设置 displayName 属性,

    function logProps(Component) {
      class LogProps extends React.Component {
        // ...
      }
    
      function forwardRef(props, ref) {
        return <LogProps {...props} forwardedRef={ref} />;
      }
    
      // Give this component a more helpful display name in DevTools.
      // e.g. "ForwardRef(logProps(MyComponent))"
      const name = Component.displayName || Component.name;
      forwardRef.displayName = `logProps(${name})`;
    
      return React.forwardRef(forwardRef);
    }

返回页首

  1. 当组件道具默认为 true 时?

    如果未传递任何 prop 的值,则默认为 true。此行为可用,以便它与 HTML 的行为匹配。

    例如,下面的表达式是等效的,

    <MyInput autocomplete />
    
    <MyInput autocomplete={true} />

    注意:不建议使用此方法,因为它可能会与 ES6 对象速记混淆(示例,它是

    {name}
    {name: name}
    )

返回页首

  1. 什么是NextJS及其主要功能?

    Next.js 是一个流行的轻量级框架,用于使用 React 构建的静态和服务器渲染应用程序。它还提供样式和路由解决方案。以下是NextJS提供的主要功能,

    1. 默认服务器呈现
    2. 自动代码拆分,加快页面加载速度
    3. 简单的客户端路由(基于页面)
    4. 基于 Webpack 的开发环境,支持 (HMR)
    5. 能够使用Express或任何其他Node.js HTTP服务器实现
    6. 可使用你自己的 Babel 和 Webpack 配置进行定制

返回页首

  1. 如何将事件处理程序传递给组件?

    可以将事件处理程序和其他函数作为 props 传递给子组件。它可以在子组件中使用,如下所示,

    <button onClick={this.handleClick}>

返回页首

  1. 在呈现方法中使用箭头函数好吗?

    是的,你可以使用。这通常是将参数传递给回调函数的最简单方法。但是你需要在使用它时优化性能。

    class Foo extends Component {
      handleClick() {
        console.log('Click happened');
      }
      render() {
        return <button onClick={() => this.handleClick()}>Click Me</button>;
      }
    }

    注意:在 render 方法中使用箭头函数会在每次组件呈现时创建一个新函数,这可能会对性能产生影响

返回页首

  1. 如何防止一个函数被多次调用?

    如果使用事件处理程序(如 onClick 或 onScroll),并且希望防止回调触发得太快,则可以限制执行回调的速率。这可以通过以下可能的方式实现,

    1. 节流:基于基于时间的频率进行更改。例如,可以使用 _.throttle lodash 函数使用它
    2. 去抖动:在一段时间不活动后发布更改。例如,可以使用 _.debounce lodash 函数使用它
    3. 请求动画帧限制:基于 requestAnimationFrame 的更改。例如,可以使用 raf-schd lodash 函数使用它

返回页首

  1. JSX 如何防止注入攻击?

    React DOM 在渲染之前转义了嵌入在 JSX 中的任何值。因此,它确保永远无法注入应用程序中未显式编写的任何内容。所有内容在呈现之前都转换为字符串。

    例如,你可以嵌入用户输入,如下所示,

    const name = response.potentiallyMaliciousInput;
    const element = <h1>{name}</h1>;

    通过这种方式,你可以防止应用程序中的XSS(跨站点脚本)攻击。

返回页首

  1. 如何更新渲染元素?

    你可以通过将新创建的元素传递给 ReactDOM 的渲染方法来更新 UI(由渲染元素表示)。

    例如,让我们以滴答作响的时钟为例,它通过多次调用 render 方法来更新时间,

    function tick() {
      const element = (
        <div>
          <h1>Hello, world!</h1>
          <h2>It is {new Date().toLocaleTimeString()}.</h2>
        </div>
      );
      ReactDOM.render(element, document.getElementById('root'));
    }
    
    setInterval(tick, 1000);

返回页首

  1. 怎么说道具是只读的?

    当你将组件声明为函数或类时,它绝不能修改自己的 props。

    让我们取一个下面的大写函数,

    function capital(amount, interest) {
       return amount + interest;
    }

    上述函数称为“pure”,因为它不会尝试更改其输入,并且始终为相同的输入返回相同的结果。因此,React 有一个规则,说“所有 React 组件在 props 方面必须像纯函数一样运行。

返回页首

  1. 你怎么说状态更新被合并了?

    当你在组件中调用 setState() 时,React 会将你提供的对象合并到当前状态中。

    例如,让我们将带有帖子和评论详细信息的 Facebook 用户作为状态变量,

      constructor(props) {
        super(props);
        this.state = {
          posts: [],
          comments: []
        };
      }

    现在,你可以使用单独的调用单独更新它们,如下所示,

    setState()

     componentDidMount() {
        fetchPosts().then(response => {
          this.setState({
            posts: response.posts
          });
        });
    
        fetchComments().then(response => {
          this.setState({
            comments: response.comments
          });
        });
      }

    如上面的代码片段所述,仅更新注释变量,而不修改或替换变量。

    this.setState({comments})
    posts

返回页首

  1. 如何将参数传递给事件处理程序?

    在迭代或循环期间,通常会将额外的参数传递给事件处理程序。这可以通过箭头函数或绑定方法实现。

    让我们以网格中更新的用户详细信息为例,

    <button onClick={(e) => this.updateUser(userId, e)}>Update User details</button>
    <button onClick={this.updateUser.bind(this, userId)}>Update User details</button>

    在这两种方法中,合成参数作为第二个参数传递。你需要为箭头函数显式传递它,并且它将自动传递给方法。

    e
    bind

返回页首

  1. 如何防止组件渲染?

    你可以通过根据特定条件返回 null 来阻止组件呈现。这样,它可以有条件地呈现组件。

    function Greeting(props) {
      if (!props.loggedIn) {
        return null;
      }
    
      return (
        <div className="greeting">
          welcome, {props.name}
        </div>
      );
    }
    class User extends React.Component {
      constructor(props) {
        super(props);
        this.state = {loggedIn: false, name: 'John'};
      }
    
      render() {
       return (
           <div>
             //Prevent component render if it is not loggedIn
             <Greeting loggedIn={this.state.loggedIn} />
             <UserDetails name={this.state.name}>
           </div>
       );
      }

    在上面的示例中,组件通过应用条件并返回 null 值来跳过其呈现部分。

    greeting

返回页首

  1. 安全使用索引作为键的条件是什么?

    有三个条件可以确保,使用索引作为键是安全的。

    1. 列表和项目是静态的 - 它们不计算也不会更改
    2. 列表中的项没有 ID
    3. 列表永远不会重新排序或筛选。

返回页首

  1. 键是否应该全局唯一?

    数组中使用的键在其同级中应该是唯一的,但它们不需要是全局唯一的。即,你可以将相同的键用于两个不同的数组。

    例如,下面的组件使用两个具有不同数组的数组,

    Book

    function Book(props) {
      const index = (
        <ul>
          {props.pages.map((page) =>
            <li key={page.id}>
              {page.title}
            </li>
          )}
        </ul>
      );
      const content = props.pages.map((page) =>
        <div key={page.id}>
          <h3>{page.title}</h3>
          <p>{page.content}</p>
          <p>{page.pageNumber}</p>
        </div>
      );
      return (
        <div>
          {index}
          <hr />
          {content}
        </div>
      );
    }

返回页首

  1. 表单处理的热门选择是什么?

    Formik
    是 react 的表单库,它提供了验证、跟踪访问过的字段和处理表单提交等解决方案。

    详细地,你可以按以下方式对它们进行分类,

    1. 将值传入和移出表单状态
    2. 验证和错误消息
    3. 处理表单提交

    它用于创建一个可扩展的、高性能的表单助手,具有最小的 API 来解决烦人的事情。

返回页首

  1. 与 redux 表单库相比,formik 的优势是什么?

    以下是推荐 formik 而不是 redux 表单库的主要原因,

    1. 表单状态本质上是短期的和局部的,因此在 Redux(或任何类型的 Flux 库)中跟踪它是不必要的。
    2. Redux-Form 在每次击键时都会多次调用整个顶级 Redux 缩减器。这样,它会增加大型应用的输入延迟。
    3. Redux-Form 是 22.5 kB 缩小的 gzip 压缩,而 Formik 是 12.7 kB

返回页首

  1. 为什么不需要使用继承?

    在 React 中,建议使用组合而不是继承来重用组件之间的代码。Props 和合成都为你提供了显式、安全地自定义组件外观和行为所需的所有灵活性。然而,如果你想在组件之间重用非UI功能,建议将其提取到一个单独的JavaScript模块中。后面的组件会导入它并使用该函数、对象或类,而不扩展它。

返回页首

  1. 我可以在 react 应用程序中使用 Web 组件吗?

    是的,你可以在 react 应用程序中使用 Web 组件。尽管许多开发人员不会使用此组合,但如果你使用的是使用 Web 组件编写的第三方 UI 组件,则可能需要这样做。

    例如,让我们使用日期选择器 Web 组件,如下所示,

    Vaadin

    import React, { Component } from 'react';
    import './App.css';
    import '@vaadin/vaadin-date-picker';
    class App extends Component {
      render() {
        return (
          <div className="App">
            <vaadin-date-picker label="When were you born?"></vaadin-date-picker>
          </div>
        );
      }
    }
    export default App;

返回页首

  1. 什么是动态导入?

    你可以使用动态导入在应用中实现代码拆分。

    让我们举一个加法的例子,

    1. 正常导入
    import { add } from './math';
    console.log(add(10, 20));
    1. 动态导入
    import("./math").then(math => {
      console.log(math.add(10, 20));
    });

返回页首

  1. 什么是可加载组件?

    如果要在服务器渲染的应用程序中执行代码拆分,建议使用可加载组件,因为 React.lazy 和 Suspense 尚不可用于服务器端渲染。可加载允许你将动态导入呈现为常规组件。

    让我们举个例子,

    import loadable from '@loadable/component'
    
    const OtherComponent = loadable(() => import('./OtherComponent'))
    
    function MyComponent() {
      return (
        <div>
          <OtherComponent />
        </div>
      )
    }

    现在,其他组件将加载到一个单独的捆绑包中

返回页首

  1. 什么是悬念成分?

    如果在父组件呈现时尚未加载包含动态导入的模块,则必须在使用加载指示器等待加载时显示一些回退内容。这可以使用悬念组件来完成。

    例如,下面的代码使用悬念组件,

    const OtherComponent = React.lazy(() => import('./OtherComponent'));
    
    function MyComponent() {
      return (
        <div>
          <Suspense fallback={<div>Loading...</div>}>
            <OtherComponent />
          </Suspense>
        </div>
      );
    }

    如上面的代码所述,悬念被包裹在惰性组件之上。

返回页首

  1. 什么是基于路由的代码拆分?

    进行代码拆分的最佳位置之一是使用路由。整个页面将立即重新呈现,因此用户不太可能同时与页面中的其他元素进行交互。因此,用户体验不会受到干扰。

    让我们举一个基于路由的网站的例子,使用像 React Router 这样的库和 React.lazy,

    import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
    import React, { Suspense, lazy } from 'react';
    
    const Home = lazy(() => import('./routes/Home'));
    const About = lazy(() => import('./routes/About'));
    
    const App = () => (
      <Router>
        <Suspense fallback={<div>Loading...</div>}>
          <Switch>
            <Route exact path="/" component={Home}/>
            <Route path="/about" component={About}/>
          </Switch>
        </Suspense>
      </Router>
    );

    在上面的代码中,代码拆分将发生在每个路由级别。

返回页首

  1. 举一个关于如何使用上下文的示例?

    上下文旨在共享可以被视为 React 组件树的全局数据。

    例如,在下面的代码中,让我们手动线程化“主题”道具,以便设置按钮组件的样式。

    //Lets create a context with a default theme value "luna"
    const ThemeContext = React.createContext('luna');
    // Create App component where it uses provider to pass theme value in the tree
    class App extends React.Component {
      render() {
        return (
          <ThemeContext.Provider value="nova">
            <Toolbar />
          </ThemeContext.Provider>
        );
      }
    }
    // A middle component where you don't need to pass theme prop anymore
    function Toolbar(props) {
      return (
        <div>
          <ThemedButton />
        </div>
      );
    }
    // Lets read theme value in the button component to use
    class ThemedButton extends React.Component {
      static contextType = ThemeContext;
      render() {
        return <Button theme={this.context} />;
      }
    }

返回页首

  1. 上下文中默认值的目的是什么?

    仅当组件在树中没有匹配的提供程序时,才使用 defaultValue 参数。这对于在不包装组件的情况下单独测试组件很有帮助。

    下面的代码片段提供默认主题值为 Luna。

    const MyContext = React.createContext(defaultValue);

返回页首

  1. 你如何使用上下文类型?

    上下文类型用于使用上下文对象。contextType 属性可以通过两种方式使用,

    1. 上下文类型作为类的属性:类上的 contextType 属性可以分配一个由 React.createContext() 创建的 Context 对象。之后,你可以在任何生命周期方法和渲染函数中使用 this.context 使用该上下文类型的最接近的当前值。

      让我们在 MyClass 上分配 contextType 属性,如下所示:

      class MyClass extends React.Component {
        componentDidMount() {
          let value = this.context;
          /* perform a side-effect at mount using the value of MyContext */
        }
        componentDidUpdate() {
          let value = this.context;
          /* ... */
        }
        componentWillUnmount() {
          let value = this.context;
          /* ... */
        }
        render() {
          let value = this.context;
          /* render something based on the value of MyContext */
        }
      }
      MyClass.contextType = MyContext;
    2. 静态字段你可以使用静态类字段通过公共类字段语法初始化上下文类型。

      class MyClass extends React.Component {
        static contextType = MyContext;
        render() {
          let value = this.context;
          /* render something based on the value */
        }
      }

返回页首

  1. 什么是消费者?

    消费者是订阅上下文更改的 React 组件。它需要一个函数作为子函数,该函数接收当前上下文值作为参数并返回一个 React 节点。传递给函数的 value 参数将等于树中上面此上下文的最接近的提供程序的值属性。

    让我们举一个简单的例子,

    <MyContext.Consumer>
      {value => /* render something based on the context value */}
    </MyContext.Consumer>

返回页首

  1. 如何在使用上下文时解决性能极端情况?

    上下文使用引用标识来确定何时重新呈现,当提供程序的父级重新呈现时,有一些陷阱可能会在使用者中触发意外呈现。

    例如,每次提供程序重新呈现时,下面的代码都会重新呈现所有使用者,因为始终会为值创建一个新对象。

    class App extends React.Component {
      render() {
        return (
          <Provider value={{something: 'something'}}>
            <Toolbar />
          </Provider>
        );
      }
    }

    这可以通过将值提升到父状态来解决,

    class App extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          value: {something: 'something'},
        };
      }
    
      render() {
        return (
          <Provider value={this.state.value}>
            <Toolbar />
          </Provider>
        );
      }
    }

返回页首

  1. HOC 中前向引用的目的是什么?

    引用不会通过,因为 ref 不是道具。React 以不同的方式处理它,就像一样。如果将 ref 添加到 HOC,则 ref 将引用最外层的容器组件,而不是包装的组件。在这种情况下,你可以使用前向引用 API。例如,我们可以使用 React.forwardRef API 显式地将 refs 转发到内部 FancyButton 组件。

    下面的 HOC 记录所有道具,

        function logProps(Component) {
          class LogProps extends React.Component {
            componentDidUpdate(prevProps) {
              console.log('old props:', prevProps);
              console.log('new props:', this.props);
            }
    
            render() {
              const {forwardedRef, ...rest} = this.props;
    
              // Assign the custom prop "forwardedRef" as a ref
              return <Component ref={forwardedRef} {...rest} />;
            }
          }
    
          return React.forwardRef((props, ref) => {
            return <LogProps {...props} forwardedRef={ref} />;
          });
        }

    让我们使用这个 HOC 来记录传递给我们的“花哨按钮”组件的所有道具,

        class FancyButton extends React.Component {
          focus() {
            // ...
          }
    
          // ...
        }
        export default logProps(FancyButton);

    现在让我们创建一个 ref 并将其传递给 FancyButton 组件。在这种情况下,你可以将焦点设置为按钮元素。

        import FancyButton from './FancyButton';
    
        const ref = React.createRef();
        ref.current.focus();
        <FancyButton
          label="Click Me"
          handleClick={handleClick}
          ref={ref}
        />;

返回页首

  1. ref 参数是否适用于所有函数或类组件?

    常规函数或类组件不接收 ref 参数,并且 ref 在 props 中也不可用。第二个 ref 参数仅在使用 React.forwardRef 调用定义组件时存在。

返回页首

  1. 为什么在使用前向引用时需要额外注意组件库?

    当你开始在组件库中使用 forwardRef 时,应将其视为重大更改并发布库的新主要版本。这是因为你的库可能具有不同的行为,例如将 ref 分配给哪些内容以及导出哪些类型。这些更改可能会破坏依赖于旧行为的应用和其他库。

返回页首

  1. 如何在没有 ES6 的情况下创建 React 类组件?

    如果你不使用 ES6,那么你可能需要改用 create-react-class 模块。对于默认 props,你需要将 getDefaultProps() 定义为传递对象上的函数。而对于初始状态,你必须提供一个单独的 getInitialState 方法来返回初始状态。

    var Greeting = createReactClass({
      getDefaultProps: function() {
          return {
            name: 'Jhohn'
          };
        },
      getInitialState: function() {
          return {message: this.props.message};
        },
      handleClick: function() {
         console.log(this.state.message);
      },
      render: function() {
        return <h1>Hello, {this.props.name}</h1>;
      }
    });

    注意:如果使用 createReactClass,则自动绑定可用于所有方法。即,你不需要对事件处理程序使用 with in 构造函数。

    .bind(this)

返回页首

  1. 是否可以在没有 JSX 的情况下使用 react ?

    是的,JSX 对于使用 React 不是强制性的。实际上,当你不想在构建环境中设置编译时,这很方便。每个 JSX 元素都只是用于调用的语法糖。

    React.createElement(component, props, ...children)

    例如,让我们以 JSX 的问候语为例,

    class Greeting extends React.Component {
      render() {
        return <div>Hello {this.props.message}</div>;
      }
    }
    
    ReactDOM.render(
      <Greeting message="World" />,
      document.getElementById('root')
    );

    你可以在没有 JSX 的情况下编写相同的代码,如下所示:

    class Greeting extends React.Component {
      render() {
        return React.createElement('div', null, `Hello ${this.props.message}`);
      }
    }
    
    ReactDOM.render(
      React.createElement(Greeting, {message: 'World'}, null),
      document.getElementById('root')
    );

返回页首

  1. 什么是差异算法?

    React 需要使用算法来找出如何有效地更新 UI 以匹配最新的树。差异算法正在生成将一棵树转换为另一棵树的最小操作数。但是,这些算法的复杂性为 O(n³),其中 n 是树中元素的数量。

    在这种情况下,显示 1000 个元素将需要大约 10 亿次比较。这太贵了。相反,React 基于两个假设实现了启发式 O(n) 算法:

    1. 不同类型的两个元素将产生不同的树。
    2. 开发人员可以使用关键道具提示哪些子元素在不同的渲染中可能是稳定的。

返回页首

  1. 差异算法涵盖哪些规则?

    当比较两个树时,React 首先比较两个根元素。行为因根元素的类型而异。它涵盖了对账算法期间的以下规则,

    1. 不同类型的元素:每当根元素具有不同的类型时,React 就会拆除旧树并从头开始构建新树。例如,不同类型的元素 to 或 from to 会导致完全重建。
    2. 相同类型的 DOM 元素:当比较两个相同类型的 React DOM 元素时,React 会查看两者的属性,保持相同的底层 DOM 节点,并且只更新更改的属性。让我们举一个具有相同 DOM 元素的示例,除了 className 属性,
      <div className="show" title="ReactJS" />
      
      <div className="hide" title="ReactJS" />
    3. 相同类型的组件元素:当组件更新时,实例保持不变,因此在渲染过程中保持该状态。React 更新底层组件实例的 props 以匹配新元素,并在底层实例上调用 componentWillReceiveProps() 和 componentWillUpdate()。之后,调用 render() 方法,diff 算法递归于上一个结果和新结果。
    4. 递归子节点:当递归于 DOM 节点的子节点时,React 只是同时迭代两个子节点列表,并在存在差异时生成突变。例如,在子树的末尾添加元素时,在这两个树之间进行转换效果很好。
      <ul>
        <li>first</li>
        <li>second</li>
      </ul>
      
      <ul>
        <li>first</li>
        <li>second</li>
        <li>third</li>
      </ul>
    5. 处理键:React 支持一个键属性。当子树有键时,React 使用该键将原始树中的子项与后续树中的子项匹配。例如,添加键可以使树转换高效,
    <ul>
      <li key="2015">Duke</li>
      <li key="2016">Villanova</li>
    </ul>
    
    <ul>
      <li key="2014">Connecticut</li>
      <li key="2015">Duke</li>
      <li key="2016">Villanova</li>
    </ul>

返回页首

  1. 什么时候需要使用引用?

    很少有用例可以参考,

    1. 管理焦点、文本选择或媒体播放。
    2. 触发命令式动画。
    3. 与第三方 DOM 库集成。

返回页首

  1. 道具必须命名为渲染道具的渲染吗?

    即使名为 render props 的模式,你也不必使用名为 render 的 prop 来使用此模式。即,任何作为组件用来知道要渲染什么的功能的道具在技术上都是“渲染道具”。让我们举一个渲染道具的孩子道具的例子,

    <Mouse children={mouse => (
      <p>The mouse position is {mouse.x}, {mouse.y}</p>
    )}/>

    实际上,子属性不需要在JSX元素的“属性”列表中命名。相反,你可以将其直接保留在元素中,

    <Mouse>
      {mouse => (
        <p>The mouse position is {mouse.x}, {mouse.y}</p>
      )}
    </Mouse>

    在使用上述技术(没有任何名称)时,明确声明子项应该是 propType 中的一个函数。

    Mouse.propTypes = {
      children: PropTypes.func.isRequired
    };

返回页首

  1. 使用纯组件的渲染道具有什么问题?

    如果在 render 方法中创建函数,则会否定纯组件的目的。因为对于新道具,浅层道具比较将始终返回 false,并且在这种情况下,每个渲染都会为渲染道具生成一个新值。你可以通过将渲染函数定义为实例方法来解决此问题。

返回页首

  1. 如何使用渲染道具创建 HOC?

    你可以使用带有渲染道具的常规组件实现大多数高阶组件 (HOC)。例如,如果你希望使用带有鼠标 HOC 而不是组件,则可以使用带有渲染道具的常规轻松创建一个组件。

    function withMouse(Component) {
      return class extends React.Component {
        render() {
          return (
            <Mouse render={mouse => (
              <Component {...this.props} mouse={mouse} />
            )}/>
          );
        }
      }
    }

    通过这种方式,渲染道具提供了使用任一模式的灵活性。

返回页首

  1. 什么是窗口技术?

    窗口化是一种在任何给定时间仅呈现一小部分行的技术,并且可以大大减少重新呈现组件所需的时间以及创建的 DOM 节点数。如果应用程序呈现长数据列表,则建议使用此技术。 React 窗口和 React 虚拟化都是流行的窗口库,它提供了几个可重用的组件来显示列表、网格和表格数据。

返回页首

  1. 如何在 JSX 中打印错误值?

    假值(如假值、空值、未定义值和真值)是有效的子值,但它们不会呈现任何内容。如果你仍然想显示它们,则需要将其转换为字符串。让我们举一个关于如何转换为字符串的示例,

    <div>
      My JavaScript variable is {String(myVariable)}.
    </div>

返回页首

  1. 门户的典型用例是什么?

    当父组件溢出时,React 门户非常有用:隐藏或具有影响堆叠上下文的属性(例如 z-index、位置、不透明度),并且你需要直观地“突破”其容器。

    例如,对话框、全局消息通知、悬停卡和工具提示。

返回页首

  1. 如何设置不受控制的组件的默认值?

    在 React 中,表单元素上的 value 属性将覆盖 DOM 中的值。对于不受控制的组件,你可能希望 React 指定初始值,但保持后续更新不受控制。若要处理这种情况,可以指定默认值属性而不是

    render() {
      return (
        <form onSubmit={this.handleSubmit}>
          <label>
            User Name:
            <input
              defaultValue="John"
              type="text"
              ref={this.input} />
          </label>
          <input type="submit" value="Submit" />
        </form>
      );
    }

    这同样适用于和输入。但是你需要使用默认检查和输入。

    select
    textArea
    checkbox
    radio

返回页首

  1. 你最喜欢的 React 堆栈是什么?

    尽管技术堆栈因开发人员而异,但最流行的堆栈用于 react 样板项目代码。它主要使用 Redux 和 redux-saga 进行状态管理和异步副作用,使用 react-router 用于路由目的,使用 styled-components 来样式化 react 组件,axios 用于调用 REST api,以及其他支持的堆栈,如 webpack、reselect、ESNext、Babel。你可以克隆项目 https://github.com/react-boilerplate/react-boilerplate 并开始处理任何新的 react 项目。

返回页首

  1. Real DOM 和 Virtual DOM 有什么区别?

    以下是Real DOM和Virtual DOM之间的主要区别,

    真正的DOM 虚拟 DOM
    更新速度很慢 更新速度很快
    DOM 操作非常昂贵。 DOM 操作非常简单
    你可以直接更新 HTML。 你无法直接更新 HTML
    它会导致太多的内存浪费 没有内存浪费
    在元素更新时创建新的 DOM 如果元素更新,它会更新 JSX

返回页首

  1. 如何将 Bootstrap 添加到 react 应用程序中?

    引导程序可以通过三种可能的方式添加到你的 React 应用程序中,

    1. 使用引导 CDN:这是添加引导的最简单方法。在 head 标签中添加引导 CSS 和 JS 资源。
    2. Bootstrap as Dependency:如果你使用的是构建工具或模块捆绑器(如 Webpack),那么这是将 Bootstrap 添加到 React 应用程序的首选选项
      npm install bootstrap
    3. React Bootstrap 包:在这种情况下,你可以将 Bootstrap 添加到我们的 React 应用程序中,方法是使用一个重新构建的 Bootstrap 组件的包,特别是作为 React 组件工作。以下软件包在此类别中很受欢迎,
      1. React 引导
      2. React

返回页首

  1. 你能列出使用 react 作为前端框架的顶级网站或应用程序吗?

    下面是使用 React 作为他们的前端框架,

    top 10 websites

    1. 脸书
    2. 优步
    3. Instagram
    4. 微信
    5. 可汗学院
    6. Airbnb
    7. 嘶��
    8. 翻板
    9. 网飞
    10. PayPal

返回页首

  1. 是否建议在 React 中使用 CSS In JS 技术?

    React 对如何定义样式没有任何意见,但如果你是初学者,那么好的起点是像往常一样在单独的 *.css 文件中定义你的样式,并使用 className 引用它们。此功能不是 React 的一部分,而是来自第三方库。但是如果你想尝试不同的方法(CSS-In-JS),那么样式化组件库是一个不错的选择。

返回页首

  1. 我需要用钩子重写我所有的类组件吗?

    不。但是你可以在一些组件(或新组件)中尝试 Hooks,而无需重写任何现有代码。因为没有计划删除 ReactJS 中的类。

返回页首

  1. 如何使用 React Hooks 获取数据?

    调用的效果钩子用于使用 axios 从 API 获取数据,并使用状态钩子的更新函数将数据设置为组件的本地状态。

    useEffect

    让我们举一个例子,它从 API 获取 React 文章列表

    import React, { useState, useEffect } from 'react';
    import axios from 'axios';
    
    function App() {
      const [data, setData] = useState({ hits: [] });
    
      useEffect(() => {
        (async () => {
          const result = await axios(
            'http://hn.algolia.com/api/v1/search?query=react',
          );
    
          setData(result.data);
        })()
      }, []);
    
      return (
        <ul>
          {data.hits.map(item => (
            <li key={item.objectID}>
              <a href={item.url}>{item.title}</a>
            </li>
          ))}
        </ul>
      );
    }
    
    export default App;

    请记住,我们提供了一个空数组作为效果钩子的第二个参数,以避免在组件更新时激活它,而仅在组件挂载时激活它。即,它仅在组件安装上获取。

返回页首

  1. Hooks 是否涵盖了类的所有用例?

    Hooks 并没有涵盖类的所有用例,但有计划很快添加它们。目前还没有与不常见的getSnapshotBeforeUpdatecomponentDidCatch生命周期等效的Hook。

返回页首

  1. 钩子支持的稳定版本是什么?

    React 在 16.8 版本中为以下软件包提供了 React Hooks 的稳定实现

    1. React DOM
    2. React DOM Server
    3. React 测试渲染器
    4. React 浅层渲染器

返回页首

  1. 为什么我们在 中使用数组解构(方括号表示法)?
    useState

    当我们用 声明一个状态变量时,它返回一对 — 一个包含两个项目的数组。第一项是当前值,第二项是更新值的函数。使用 [0] 和 [1] 访问它们有点令人困惑,因为它们具有特定的含义。这就是我们使用数组解构的原因。

    useState

    例如,数组索引访问如下所示:

     var userStateVariable = useState('userProfile'); // Returns an array pair
     var user = userStateVariable[0]; // Access first item
     var setUser = userStateVariable[1]; // Access second item

    而通过数组解构,可以按如下方式访问变量:

    const [user, setUser] = useState('userProfile');

    返回页首

  2. 引入钩子的来源是什么?

    胡克斯从几个不同的来源得到了这些想法。以下是其中的一些,

    1. 以前在 react-future 存储库中使用函数式 API 的实验
    2. 使用渲染道具 API(如 React 组件)进行社区实验
    3. DisplayScript 中的状态变量和状态单元格。
    4. Rx 中的订阅。
    5. ReasonReact中的减速器组件。

返回页首

  1. 如何访问 Web 组件的命令式 API?

    Web 组件通常公开命令式 API 来实现其功能。如果你想访问 Web 组件的命令式 API,你将需要使用 ref 直接与 DOM 节点交互。但是,如果你使用的是第三方 Web 组件,最好的解决方案是编写一个充当 Web 组件包装器的 React 组件。

返回页首

  1. 什么是福米克?

    Formik 是一个小型的 React 表单库,可帮助你解决三个主要问题,

    1. 将值传入和移出表单状态
    2. 验证和错误消息
    3. 处理表单提交

返回页首

  1. 在 Redux 中处理异步调用的典型中间件选择是什么?

    在 Redux 生态系统中处理异步调用的一些流行的中间件选择是 。
    Redux Thunk, Redux Promise, Redux Saga

返回页首

  1. 浏览器能理解 JSX 代码吗?

    不,浏览器无法理解 JSX 代码。你需要一个转译器来将你的JSX转换为浏览器可以理解的常规Javascript。目前使用最广泛的转译器是 Babel。

返回页首

  1. 描述 React 中的数据流?

    React 使用减少样板的 props 实现单向 React 式数据流,并且比传统的双向数据绑定更容易理解。

返回页首

  1. 什么是 React 脚本?

    该软件包是来自创建- React -应用程序入门包的一组脚本,可帮助你在不进行配置的情况下启动项目。该命令设置开发环境并启动服务器,以及热模块重新加载。
    react-scripts
    react-scripts start

返回页首

  1. 创建 React 应用程序有哪些功能?

    以下是创建 React 应用程序提供的一些功能的列表。

    1. React,JSX,ES6,Typescript和Flow语法支持。
    2. 带有自动前缀的 CSS
    3. CSS 重置/规范化
    4. 实时开发服务器
    5. 快速交互式单元测试运行程序,内置对覆盖率报告的支持
    6. 一个构建脚本,用于捆绑 JS、CSS 和映像以供生产,带有哈希和源映射
    7. 脱机优先服务辅助角色和 Web 应用清单,满足所有渐进式 Web 应用条件。

返回页首

  1. renderToNodeStream 方法的目的是什么?

    该方法用于在服务器上生成 HTML,并在初始请求时向下发送标记以加快页面加载速度。它还可以帮助搜索引擎出于SEO目的轻松抓取你的页面。注意:请记住,此方法在浏览器中不可用,而仅在服务器中可用。
    ReactDOMServer#renderToNodeStream

返回页首

  1. 什么是MobX?

    MobX is a simple, scalable and battle tested state management solution for applying functional reactive programming (TFRP). For reactJs application, you need to install below packages,
    npm install mobx --save
    npm install mobx-react --save

Back to Top

  1. What are the differences between Redux and MobX?

    Below are the main differences between Redux and MobX,

    Topic Redux MobX
    Definition It is a javascript library for managing the application state It is a library for reactively managing the state of your applications
    Programming It is mainly written in ES6 It is written in JavaScript(ES5)
    Data Store There is only one large store exist for data storage There is more than one store for storage
    Usage Mainly used for large and complex applications Used for simple applications
    Performance Need to be improved Provides better performance
    How it stores Uses JS Object to store Uses observable to store the data

Back to Top

  1. Should I learn ES6 before learning ReactJS?

    No, you don’t have to learn es2015/es6 to learn react. But you may find many resources or React ecosystem uses ES6 extensively. Let's see some of the frequently used ES6 features,

    1. Destructuring: To get props and use them in a component
      // in es 5
       var someData = this.props.someData
       var dispatch = this.props.dispatch
      
      // in es6
      const { someData, dispatch } = this.props
    2. Spread operator: Helps in passing props down into a component
      // in es 5
      <SomeComponent someData={this.props.someData} dispatch={this.props.dispatch} />
      
      // in es6
      <SomeComponent {...this.props} />
    3. Arrow functions: Makes compact syntax
      // es 5
      var users = usersList.map(function (user) {
       return <li>{user.name}</li>
      })
      // es 6
      const users = usersList.map(user => <li>{user.name}</li>);

Back to Top

  1. What is Concurrent Rendering?

    The Concurrent rendering makes React apps to be more responsive by rendering component trees without blocking the main UI thread. It allows React to interrupt a long-running render to handle a high-priority event. i.e, When you enabled concurrent Mode, React will keep an eye on other tasks that need to be done, and if there's something with a higher priority it will pause what it is currently rendering and let the other task finish first. You can enable this in two ways,

    // 1. Part of an app by wrapping with ConcurrentMode
    <React.unstable_ConcurrentMode>
      <Something />
    </React.unstable_ConcurrentMode>
    
    // 2. Whole app using createRoot
    ReactDOM.unstable_createRoot(domNode).render(<App />);

Back to Top

  1. What is the difference between async mode and concurrent mode?

    Both refers the same thing. Previously concurrent Mode being referred to as "Async Mode" by React team. The name has been changed to highlight React’s ability to perform work on different priority levels. So it avoids the confusion from other approaches to Async Rendering.

Back to Top

  1. Can I use javascript urls in react16.9?

    Yes, you can use javascript: URLs but it will log a warning in the console. Because URLs starting with javascript: are dangerous by including unsanitized output in a tag like and create a security hole.

    <a href>

    const companyProfile = {
      website: "javascript: alert('Your website is hacked')",
    };
    // It will log a warning
    <a href={companyProfile.website}>More details</a>

    Remember that the future versions will throw an error for javascript URLs.

Back to Top

  1. What is the purpose of eslint plugin for hooks?

    The ESLint plugin enforces rules of Hooks to avoid bugs. It assumes that any function starting with ”use” and a capital letter right after it is a Hook. In particular, the rule enforces that,

    1. Calls to Hooks are either inside a PascalCase function (assumed to be a component) or another useSomething function (assumed to be a custom Hook).
    2. Hooks are called in the same order on every render.

Back to Top

  1. What is the difference between Imperative and Declarative in React?

    Imagine a simple UI component, such as a "Like" button. When you tap it, it turns blue if it was previously grey, and grey if it was previously blue.

    The imperative way of doing this would be:

    if( user.likes() ) {
        if( hasBlue() ) {
            removeBlue();
            addGrey();
        } else {
            removeGrey();
            addBlue();
        }
    }

    Basically, you have to check what is currently on the screen and handle all the changes necessary to redraw it with the current state, including undoing the changes from the previous state. You can imagine how complex this could be in a real-world scenario.

    In contrast, the declarative approach would be:

    if( this.state.liked ) {
        return <blueLike />;
    } else {
        return <greyLike />;
    }

    Because the declarative approach separates concerns, this part of it only needs to handle how the UI should look in a sepecific state, and is therefore much simpler to understand.

Back to Top

  1. What are the benefits of using typescript with reactjs?

    Below are some of the benefits of using typescript with Reactjs,

    1. It is possible to use latest JavaScript features
    2. Use of interfaces for complex type definitions
    3. IDEs such as VS Code was made for TypeScript
    4. Avoid bugs with the ease of readability and Validation

    Back to Top

  2. How do you make sure that user remains authenticated on page refresh while using Context API State Management?

When a user logs in and reload, to persist the state generally we add the load user action in the useEffect hooks in the main App.js. While using Redux, loadUser action can be easily accessed.

App.js

import {loadUser}  from '../actions/auth';
store.dispatch(loadUser());
  • But while using Context API, to access context in App.js, wrap the AuthState in index.js so that App.js can access the auth context. Now whenever the page reloads, no matter what route you are on, the user will be authenticated as loadUser action will be triggered on each re-render.

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import AuthState from './context/auth/AuthState'

ReactDOM.render(
  <React.StrictMode>
    <AuthState>
      <App />
    </AuthState>
  </React.StrictMode>,
  document.getElementById('root')
);

App.js

  const authContext = useContext(AuthContext);

  const { loadUser } = authContext;

  useEffect(() => {
    loadUser();
  },[])

loadUser

    const loadUser = async () => {
        const token = sessionStorage.getItem('token');

        if(!token){
            dispatch({
                type: ERROR
            })
        }
        setAuthToken(token);

        try {
            const res = await axios('/api/auth'); 

            dispatch({
                type: USER_LOADED,
                payload: res.data.data
            })
            
        } catch (err) {
           console.error(err); 
        }
    }

Back to Top

  1. What are the benefits of new JSX transform?

    There are three major benefits of new JSX transform,

    1. It is possible to use JSX without importing React packages
    2. The compiled output might improve the bundle size in a small amount
    3. The future improvements provides the flexibility to reduce the number of concepts to learn React.

Back to Top

  1. How is the new JSX transform different from old transform??

    The new JSX transform doesn’t require React to be in scope. i.e, You don't need to import React package for simple scenarios.

    Let's take an example to look at the main differences between the old and the new transform,

    Old Transform:

    import React from 'react';
    
    function App() {
      return <h1>Good morning!!</h1>;
    }

    Now JSX transform convert the above code into regular JavaScript as below,

    import React from 'react';
    
    function App() {
      return React.createElement('h1', null, 'Good morning!!');
    }

    New Transform:

    The new JSX transform doesn't require any React imports

    function App() {
      return <h1>Good morning!!</h1>;
    }

    Under the hood JSX transform compiles to below code

    import {jsx as _jsx} from 'react/jsx-runtime';
    
    function App() {
      return _jsx('h1', { children: 'Good morning!!' });
    }

    Note: You still need to import React to use Hooks.

Back to Top

  1. How do you get redux scaffolding using create-react-app?

    Redux team has provided official redux+js or redux+typescript templates for create-react-app project. The generated project setup includes,

    1. Redux Toolkit and React-Redux dependencies
    2. Create and configure Redux store
    3. React-Redux passing the store to React components
      <Provider>
    4. Small "counter" example to demo how to add redux logic and React-Redux hooks API to interact with the store from components

    The below commands need to be executed along with template option as below,

    1. Javascript template:
    npx create-react-app my-app --template redux
    1. Typescript template:
    npx create-react-app my-app --template redux-typescript

Back to Top

  1. What are React Server components?

    React Server Component is a way to write React component that gets rendered in the server-side with the purpose of improving React app performance. These components allow us to load components from the backend.

    Note: React Server Components is still under development and not recommended for production yet.

Back to Top

  1. What is prop drilling?

    Prop Drilling is the process by which you pass data from one component of the React Component tree to another by going through other components that do not need the data but only help in passing it around.

Back to Top

  1. What is state mutation and how to prevent it?

    State mutation
    happens when you try to update the state of a component without actually using function. This can happen when you are trying to do some computations using a state variable and unknowingly save the result in the same state variable. This is the main reason why it is advised to return new instances of state variables from the reducers by using Object.assign({}, ...) or spread syntax.
    setState

    This can cause unknown issues in the UI as the value of the state variable got updated without telling React to check what all components were being affected from this update and it can cause UI bugs.

    Ex:

    class A extends React.component {
      constructor(props) {
        super(props);
        this.state = {
          loading: false
        }
     }
    
    componentDidMount() {
      let { loading } = this.state;
      loading = (() => true)(); // Trying to perform an operation and directly saving in a state variable
    }

    How to prevent it: Make sure your state variables are immutable by either enforcing immutability by using plugins like Immutable.js, always using to make updates, and returning new instances in reducers when sending updated state values.

    setState

Back to Top

  1. What is the difference between useState and useRef hook?

    1. useState causes components to re-render after state updates whereas useRef doesn’t cause a component to re-render when the value or state changes. Essentially, useRef is like a “box” that can hold a mutable value in its (.current) property.
    2. useState allows us to update the state inside components. While useRef allows refrencing DOM elements.

Back to Top

  1. What are the Differences Between Functional and Class Component

Class Component syntax

class Example extends Reacts.Component {
render(){
return <h1>This is a class component</h1>}
}

I guess we all know that Pascal Case is the accepted way of naming a component in react.

Example

Functional Component syntax

Functional component has been improved over the years with some added features like Hooks Here is a syntax for functional component

function App(){
   return <div className="App">
     <h1>Hello, I'm a Nigerian</h1>
    </div>
}

States in Class Component

states holds information or data about a component in react which may change over time. in class component we can update the state, when a user interacts with it or maybe a server response using the method and the initial state is been assigned in the method using the the object. different data type can be passed in the this.state object, which can be string, boolean, numbers, etc. A simple example showing how we use the setState() and constructor()

setState()
Constructor( ) 
 this.state

class Example extends Component {
  constructor() {
    super();
    this.state = {
      example: "This is a class component",
    };
  }
  changeText() {
    this.setState({
      example: "implementing the setState() in class component",
    });
  }
  render() {
    return (
      <>
        <h1>{this.state.example}</h1>
        <button
          onClick={() => {
            this.changeText();
          }}>
          Click!!
        </button>
      </>
    );
  }
}

Using Sates in Functional Components

Initially, we could not use state in functional components because it was only supported in class components. over the years hooks were implemented in functional component. The hooks that enable us to use state in functional component is called useState The useState( ) hook returns an array of the current state and a function ( setState) that we can use to update the value of the current state. The array is being destructured so we can can see the variables the array holds that is, the initial state and the updated state lets see an example

function App() {
  const [country, setCountry] = useState("i'm a Nigerian");
  const change = () => {
    setCountry("i am a Canadian");
  };
  return (
    <div className="App">
      <h1>Hello, {country} </h1>
      <button onClick={change}>Change</button>
    </div>
  );
}

Props in Class Component

道具被称为“属性”。props 被传递到 react 组件中,就像参数被传递到函数中一样。道具被指定为属性,就像你的 html 一样。例如,如果 name 属性是 “name”,我们给 name 赋值。所以基本上,props 是包含属性及其相应值的对象。数据可以从父组件传递到子组件,但这些数据是不可变的,这意味着我们不能跨另一个组件修改 props。下面是一个示例 ''' 类 介绍扩展了 React.Component { render() { return

你好,我的名字是{this.props.name}

; } }

class App extensions React.Component { render() { return (

); } }
## Props in Functional Components

Props in functional components are similar to that of the class components, the difference is the absence of the 'this' keyword. We also destructure in a similar way without the 'this' keyword. they are also immutable in the functional component

函数 食物(道具) { 返回

我爱{props.fav}

; }

函数 App() { return (

); }
> As you can see in the example above there wasn't a need for the 'this' keyword.

函数 食物(道具) { const { fav } = props; return

我爱{fav}

; }

函数 App() { return (

); }
summary:

*The functional components doesn't require the render method          
*Class component require the render() method that returns JSX.                                                  

To use states in functional component we use the **useState** hook.          
To use State in class components we use the constructor method and the setState function.
                                     
Functional components use the useEffect hook instead of lifecycle method [useEffect](https://www.w3schools.com/react/react_useeffect.asp )    
 Class components uses Lifecycle method    **componentWillUnmount** etc. [ Lifecycle methods](https://www.w3schools.com/react/react_lifecycle.asp )

  **[⬆ Back to Top](#table-of-contents)**





## Disclaimer

The questions provided in this repository are the summary of frequently asked questions across numerous companies. We cannot guarantee that these questions will actually be asked during your interview process, nor should you focus on memorizing all of them. The primary purpose is for you to get a sense of what some companies might ask — do not get discouraged if you don't know the answer to all of them ⁠— that is ok!

Good luck with your interview 😊

---