React基础
基于create-react-app进行React学习,React个人感觉与Vue最大的区别在于高复用性,每一个组件都只做一件事,组件的业务逻辑可以放在父级去做(状态提升)。这与Vue2.0相差甚大,不过随着Vue3.0的到来,Vue也完全可以采取这种方式。弊端是React采用jsx、tsx进行DOM书写,需要额外学习一下语法糖,不过都是小问题🙁
Props State
React为向下数据流(因此我们可以将父组件的state传递到子组件),因此可以状态提升(状态提升就是把子组件的state提升到父组件)
Props
用来父子间传递数据,function
下可直接 (props) => props[key] || props.”key”,class
下需要this.props[key] || this.props.”key”
State
不要直接修改State,修改State最好使用setState()
进行修改,否则页面可能不会刷新
State的更新可能是异步的,React出于性能考虑,会把多个setState
合并为一个调用,因此State更新可能是异步的,如何让其能快速更新到dom呢?
State的更新会被合并
列表 key 类似Vue v-for key
Fragments 类似Vue Template
React 中的一个常见模式是一个组件返回多个元素。Fragments 允许你将子列表分组,而无需向 DOM 添加额外节点。
使用
1 | render() { |
短语法不支持key
属性
1 | class Columns extends React.Component { |
React.lazy
像渲染常规组件一样处理动态引入的(组件)
1 | import React, { Suspense } from 'React' |
React.createContext
类似Vue中的provide inject吧,但是React中就没有那么好用了…,如果在不需要监听器变化的情况下,声明外部变量感觉更好用一点。
错误辩解 Error Boundaries
React16之后引入,目的是捕获并打印发生在其子组件树任何位置的JavaScript错误,并且,渲染备用UI
无法捕获时间处理、异步代码、服务端渲染以及其自身抛出的错误
如果一个 class 组件中定义了 static getDerivedStateFromError() 或 componentDidCatch() 这两个生命周期方法中的任意一个(或两个)时,那么它就变成一个错误边界。当抛出错误后,请使用 static getDerivedStateFromError() 渲染备用 UI ,使用 componentDidCatch() 打印错误信息。
ErrorBoundary
1 | class ErrorBoundary extends React.Component { |
Refs
🙁感觉不会经常用到
HOC 高阶组件
🙁
不要在render中使用 Refs不会被传递
JSX
组件名大写 JSX不能是一个表达式 Boolean、Null、Undefined将被忽略不会渲染
1 | function Story(props) { |
Portals
Portal提供了一种将子节点渲染到父节点以外的DOM节点的方案
1 | ReactDOM.createPortal(child, container) // 语法 |
child是任何可渲染的React子元素,container是一个DOM元素
Profiler
Profiler 测量渲染一个 React 应用多久渲染一次以及渲染一次的“代价”。 它的目的是识别出应用中渲染较慢的部分,只能应用于开发环境
StrictMode
严格模式,只能应用于开发环境
React 生命周期
react-lifecycle-methods-diagram
挂载
当组件实例被创建并插入 DOM 中时,其生命周期调用顺序如下:
更新
当组件的 props 或 state 发生变化时会触发更新。组件更新的生命周期调用顺序如下:
static getDerivedStateFromProps()
shouldComponentUpdate()
render()
getSnapshotBeforeUpdate()
componentDidUpdate()
卸载
当组件从 DOM 中移除时会调用如下方法:
错误处理
当渲染过程,生命周期,或子组件的构造函数中抛出错误时,会调用如下方法:
其他 APIs
组件还提供了一些额外的 API:
class 属性
实例属性
ReactDOM
- render 渲染元素
- hydrate 与render相同
- unmountComponentAtNode 从DOM中卸载组件,会一并清除state
- findDOMNode 如果组件已经被渲染在DOM上,返回响应的原生DOM元素
- findDOMNode 创建portal Portal提供了一种将子节点渲染到父节点以外的DOM节点的方案
ReactDOMServer
ReactDOMServer 对象允许你将组件渲染成静态标记。通常,它被使用在 Node 服务端上
DOM
dangerouslySetInnerHTML
dangerouslySetInnerHTML 是 React 为浏览器 DOM 提供 innerHTML 的替换方案。通常来讲,使用代码直接设置 HTML 存在风险,因为很容易无意中使用户暴露于跨站脚本(XSS)的攻击。因此,你可以直接在 React 中设置 HTML,但当你想设置 dangerouslySetInnerHTML 时,需要向其传递包含 key 为 __html 的对象,以此来警示你。例如:
1 | function createMarkup() { |
htmlFor 由于 for 在 JavaScript 中是保留字,所以 React 元素中使用了 htmlFor 来代替。
suppressContentEditableWarning
通常,当拥有子节点的元素被标记为 contentEditable 时,React 会发出一个警告,因为这不会生效。该属性将禁止此警告。尽量不要使用该属性,除非你要构建一个类似 Draft.js 的手动管理 contentEditable 属性的库。
suppressHydrationWarning
如果你使用 React 服务端渲染,通常会在当服务端与客户端渲染不同的内容时发出警告。但是,在一些极少数的情况下,很难甚至于不可能保证内容的一致性。例如,在服务端和客户端上,时间戳通常是不同的。
如果设置 suppressHydrationWarning 为 true,React 将不会警告你属性与元素内容不一致。它只会对元素一级深度有效,并且打算作为应急方案。因此不要过度使用它。你可以在 ReactDOM.hydrate() 文档 中了解更多关于 hydration 的信息
React采用小驼峰式命名,多DOM的支持有
1 | accept acceptCharset accessKey action allowFullScreen alt async autoComplete |
合成事件
SyntheticEvent 实例将被传递给你的事件处理函数,它是浏览器的原生事件的跨浏览器包装器。除兼容所有浏览器外,它还拥有和浏览器原生事件相同的接口,包括 stopPropagation() 和 preventDefault()。
Hook 简介
在Function中使用一些Class中拥有的属性
每个组件间的 state 是完全独立的。Hook 是一种复用状态逻辑的方式,它不复用 state 本身。事实上 Hook 的每次调用都有一个完全独立的 state —— 因此你可以在单个组件中多次调用同一个自定义 Hook。
自定义 Hook 更像是一种约定而不是功能。如果函数的名字以 “use” 开头并调用其他 Hook,我们就说这是一个自定义 Hook。
Hook 概览
useState
1 | import React, { useState } from 'react'; |
惰性初始state
initialState
参数只会在组件的初始渲染中起作用,后续渲染时会被忽略。如果初始 state 需要通过复杂计算获得,则可以传入一个函数,在函数中计算并返回初始的 state,此函数只在初始渲染时被调用
1 | const [state, setState] = useState(() => { |
useEffect
useEffect 就是一个 Effect Hook,给函数组件增加了操作副作用的能力。它跟 class 组件中的 componentDidMount、componentDidUpdate 和 componentWillUnmount 具有相同的用途,只不过被合并成了一个 API。(我们会在使用 Effect Hook 里展示对比 useEffect 和这些方法的例子。)
1 | import React, { useState, useEffect } from 'react'; |
第二个参数 effect所依赖的数值,只有当这个值变化时才会更新
1 | useEffect( |
useContext
useContext 让你不使用组件嵌套就可以订阅 React 的 Context。
接收一个 context 对象(React.createContext 的返回值)并返回该 context 的当前值。当前的 context 值由上层组件中距离当前组件最近的 <MyContext.Provider> 的 value prop 决定
1 | const themes = { |
useReducer
useReducer 可以让你通过 reducer 来管理组件本地的复杂 state
useState 的替代方案。它接收一个形如 (state, action) => newState 的 reducer,并返回当前的 state 以及与其配套的 dispatch 方法。
useCallback
useMemo
useRef
useImperativeHandle
useLayoutEffect
useDebugValue
Hook使用规则
- 只能在函数最外层调用Hook,不要在循环、条件判断或者子函数中调用
- 只能在React的函数组件中调用Hook。不要在其他JavaScript函数中调用。