文档地址:https://react.dev/learn
react@18.2.0
Add React to a Website
transform JSX into HTML by add the Babel compiler
simple demos:
<script src="like-button.js" type="text/babel"></script>
a project:
babel-preset-react-app
Built-in React Components
<Fragment>
or <>...</>
- 做不可见的包裹元素
<Profiler>
-
测量 React 树的渲染开销,需要两个 prop:
id
(string)-
onRender
(function):当组件树中的组件“提交”更新的时候被 React 调用的回调函数,它的参数描述了渲染了什么和花费了多久。function onRenderCallback( id, // string,发生提交的 Profiler 树的 “id”,如果有多个 profiler,它能用来分辨树的哪一部分发生了“提交” phase, // "mount" | "update" - 判断是组件树的第一次装载引起的重渲染,还是由 props、state 或是 hooks 改变引起的重渲染 actualDuration, // number,本次更新在渲染 Profiler 和它的子代上花费的时间 baseDuration, // number,在 Profiler 树中最近一次每一个组件 render 的持续时间。 这个值估计了最差的渲染时间 startTime, // number,本次更新中 React 开始渲染的时间戳 commitTime, // number,本次更新中 React commit 阶段结束的时间戳 interactions // Set,属于本次更新的 interactions 的集合,(例如当 render 或者 setState 被调用时) ) { // 合计或记录渲染时间。。。 }
<Suspense>
- 将 Suspense 组件置于懒加载组件之上的任何位置,甚至可以用一个 Suspense 组件包裹多个懒加载组件,fallback 属性接受任何在组件加载过程中你想展示的 React 元素。
<StrictMode>
- 用来突出显示应用程序中潜在的问题,不会渲染任何可见的 UI,为其后代元素触发额外的检查和警告,仅在开发模式下运行。
Built-in React Hooks
useState(initialState)
若参数为函数(
fn
),则React
仅在初次渲染时调用它,并将其值存储为初始状态。该函数应为纯函数,且无参数,有返回值若参数为函数调用(
fn()
),则该函数每次re-rendering
都会被调用-
set
函数只更新下一次render
的state
- 若
nextState
为函数,React
将更新函数放在一个队列中,在下一次渲染期间调用
- 若
如果
newState === oldState
(Object.is
),React
将跳过re-rendering
React 批处理状态更新
useContext(SomeContext)
- 接收一个 context 对象并返回该 context 的当前值
useReducer(reducer, initialArg, init?)
用
reducer
管理组件的state
若指定
init
,则初始状态为init(initialArg)
,否则为initialArg
-
若第二个参数为函数:
const [state, dispatch] = useReducer(reducer, createInitialState(username))
虽然函数调用结果即
createInitialState(username)
只会用于初次渲染,但是每次render
时createInitialState
都会被调用,所以应将该函数作为第三个参数进行传递
useRef(initialValue)
用来存储
render
不需要的值,或操纵DOM
改变
ref
不会触发re-render
若
initialValue
为函数,则每次render
都会被调用
useCallback(fn, dependencies)
- 缓存函数本身
useMemo(calculateValue, dependencies)
- 缓存调用函数的结果
useEffect(setup, dependencies?)
-
异步执行,用法:
useEffect(() => { // 执行逻辑 // 清除 effect return () => { // XXXXX } })
mounts:setup run
-
当依赖项发生变化,执行下一个 effect 之前,会清除上一个 effect
cleanup run with the old props and state
setup run with the new props and state
unmounts:cleanup run
setup
:有副作用代码的函数,在组件渲染到屏幕之后(浏览器完成布局与绘制之后)执行-
dependencies
:不传递参数:在每轮组件渲染结束后执行
[]
:初始渲染之后执行一次[dep1, dep2, dep3]
:初始渲染之后以及依赖项发生变化(使用Object.is
比较)时执行
useLayoutEffect(setup, dependencies?)
用法同
uesEffect
,阻塞浏览器重绘在所有 DOM 变更 之后 同步调用 effect,可以使用它来读取 DOM 布局并同步触发重渲染
在浏览器执行绘制之前,
useLayoutEffect
内部的更新计划将被同步刷新
useInsertionEffect(setup, dependencies?)
用法同
uesEffect
在所有 DOM 突变 之前 同步触发
无法在
useInsertionEffect
内部访问refs
以及更新state
应仅限于在
css-in-js
库中注入动态style
useDebugValue(value, format?)
用于在 React 开发者工具中显示自定义 hook 的标签,无返回值
value
:想在开发者工具中显示的值format
:格式化函数,若指定,则显示format(value)
,否则显示value
useDeferredValue(value)
用于延迟更新UI,返回该值的延迟版本。
value
为想要延迟的值使用场景:input + result-list
-
与防抖(Debouncing )、节流(Throttling )比较:
防抖:在更新列表之前等待用户停止输入(例如一秒钟)
节流:每隔一段时间更新一次列表(例如最多每秒一次)
-
deferredValue
:不需要选择任何固定延迟。如果用户的设备速度很快,则延迟重新渲染几乎会立即发生。如果用户的设备速度很慢,列表将“滞后于”输入。
可中断。如果 React 正在渲染大量列表时,用户再次输入,React 将中断渲染,处理键入。而防抖和节流是阻塞的,仅仅是延迟渲染。
useId()
生成唯一 ID,ID 为包含
:
的字符串 token(:XXX:
有助于确保 token 是唯一的)不应用于在列表中生成 key
useImperativeHandle(ref, createHandle, dependencies?)
:
- 向父组件暴露 DOM
import { forwardRef } from 'react';
const MyInput = forwardRef(function MyInput(props, ref) {
return <input {...props} ref={ref} />;
});
向父组件暴露方法
用法:与
forwardRef
一起使用
import { forwardRef, useImperativeHandle } from 'react';
const MyInput = forwardRef(function MyInput(props, ref) {
useImperativeHandle(ref, () => {
return {
// ... your methods ...
};
}, []);
return <input {...props} />;
});
-
参数:
ref
:从forwardRef
中接收到的参数createHandle
:一个不带参数的函数,返回一个带有要公开的方法的对象dependencies
:createHandle
函数内部引用的依赖值
useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot?)
用来订阅外部数据,返回当前的数据快照。数据变化时,触发组件重渲染
-
可用于订阅浏览器API
subscribe
:函数,参数为回调函数,用来订阅store
,且需返回unsubscribes
。当数据变化时,回调函数被调用,触发组件重渲染。getSnapshot
:函数,返回数据快照getServerSnapshot
:函数,返回数据的初始快照。若省略该参数,服务端渲染时将报错
useTransition()
mark some state updates as transitions
-
const [isPending, startTransition] = useTransition()
isPending
:指明这个transitions
是否在加载中startTransition
:将回调函数中的update state
标记为transitions
Built-in React APIs
createContext
-
define and provide context to the child components
const SomeContext = createContext(defaultValue)
-
provide the context value to components:
SomeContext.Provider
-
read the context value:
SomeContext.Consumer
(不推荐)const value = useContext(SomeContext)
forwardRef
将
DOM
节点暴露给父组件-
配合
useImperativeHandle
,暴露state
或function
给父组件const SomeComponent = forwardRef(function MyComponent(props, ref) {})
lazy
-
lets you defer loading a component’s code until it’s rendered for the first time
const SomeComponent = lazy(load)
load
: A function that returns a Promise or another thenable (a Promise-like object with athen
method)
memo
-
lets your component skip re-renders with same props
const MemoizedComponent = memo(SomeComponent, arePropsEqual?)
arePropsEqual
:function arePropsEqual(oldProps, newProps) {}
startTransition
-
mark a state update as a transition, update the state without blocking the UI
startTransition(scope)
react-dom@18.2.0
React DOM APIs
createPortal
-
render some children into a different part of the DOM
createPortal(children, domNode)
flushSync
-
强制 React 同步刷新提供的回调中的任何更新,确保了 DOM 立即更新,不推荐使用
flushSync(callback)
Client React DOM APIs
createRoot
-
lets you create a root to display React components inside a browser DOM node
const root = createRoot(domNode, options?)
hydrateRoot
-
lets you display React components inside a browser DOM node whose HTML content was previously generated by
react-dom/server
const root = hydrateRoot(domNode, reactNode, options?)