React最佳实践
React
事件机制,合成事件
是什么
React 基于浏览器的事件机制⾃身实现了⼀套事件机制,包括事件注册、事件的合成、事件冒泡、事件派发等。
在 React 中这套事件机制被称之为合成事件
工作过程
1 | import React from 'react'; |
最终输出
1 | 原⽣事件:⼦元素 DOM 事件监听! |
总结
- React 上注册的事件最终会绑定在document这个 DOM 上,⽽不是 React 组件对应的 DOM(减少内存开销就是因为所有的事件都绑定在 document 上,其他节点没有绑定事件)
- React 通过队列的形式,从触发的组件向⽗组件回溯,然后调⽤他们 JSX 中定义的 callback
- React 有⼀套⾃⼰的合成事件 SyntheticEvent
CSS引入
在组件内直接使⽤
内联style引入
组件中引⼊ .css ⽂件
全局生效,样式之间会互相影响
组件中引⼊ .module.css ⽂件
将 css ⽂件作为⼀个模块引⼊,这个模块中的所有 css ,只作⽤于当前组件。不会影响当前组件的后代组件
这种⽅式是 webpack 特⼯的⽅案,只需要配置 webpack 配置⽂件中 modules:true
即可
CSS in JS
CSS-in-JS, 是指⼀种模式,其中 CSS 由 JavaScript ⽣成⽽不是在外部⽂件中定义
此功能并不是 React 的⼀部分,⽽是由第三⽅库提供,例如:
- styled-components
- emotion
- glamorous
本质是通过函数的调⽤,最终创建出⼀个组件:
- 这个组件会被⾃动添加上⼀个不重复的class
- styled-components会给该class添加相关的样式
组件通信
高阶组件
本质上是一个函数,接收一个或多个组件作为参数,并返回一个组件
错误边界
错误边界是一种 React 组件,这种组件可以捕获发生在其子组件树任何位置的 JavaScript 错误,并打印这些错误,同时展示降级 UI,而并不会渲染那些发生崩溃的子组件树。错误边界可以捕获发生在整个子组件树的渲染期间、生命周期方法以及构造函数中的错误。
形成错误边界组件的两个条件:
- 使⽤了
static getDerivedStateFromError()
- 使⽤了
componentDidCatch()
抛出错误后,使⽤static getDerivedStateFromError()
渲染备⽤ UI ,使⽤ componentDidCatch() 打印错误信息,如下:
1 | class ErrorBoundary extends React.Component { |
下⾯这些情况⽆法捕获到异常:
- 事件处理
- 异步代码(例如 setTimeout 或 requestAnimationFrame 回调函数)
- 服务端渲染
- 它自身抛出来的错误(仅能捕获子组件抛出的错误)
setState更新,批量更新
render原理(jsx经过babel编译)、render触发时机
Diff算法
React Portal
Portal 提供了一种将子节点渲染到存在于父组件以外的 DOM 节点的优秀的方案。ReactDOM.createPortal(child, container)
第一个参数(child)是任何可渲染的 React 子元素,例如一个元素,字符串或 fragment。第二个参数(container)是一个 DOM 元素。
React router
是什么
react-router 等前端路由的原理⼤致相同,可以实现⽆刷新的条件下切换显示不同的⻚⾯
路由的本质就是⻚⾯的 URL 发⽣改变时,⻚⾯的显示结果可以根据 URL 的变化⽽变化,但是⻚⾯不会刷新因此,可以通过前端路由可以实现单⻚(SPA)应⽤
模式
HashRouter(Hash模式)
- 采用监听
window
上的hashchange
事件实现; - path的表现形式是
localhost:3000/#/demo/test
; - 服务器无须做额外配置(因为对于服务器而言,
http://example.com/#/home
和http://example.com
这两个请求在服务器看来是完全一样的,因为服务器只处理http://example.com
这个部分,而#/home
这个哈希部分的变化不会触发新的服务器请求)
BrowserRouter(History模式)
BrowserRouter
使用的是H5的history API来实现;- path的表现形式是
localhost:3000/demo/test
; - 服务器需要进行额外的配置(当path变化时,浏览器会向服务器发送请求。服务器需要能够识别这些请求并返回正确的页面或者资源。例如,在服务器重定向配置中,需要设置一个通配符路由(
*
)来处理所有可能的路由请求,将请求重定向到应用的入口文件(通常是index.html
),这样客户端的 JavaScript 代码才能根据 URL 中的路径来正确地渲染页面)