From 864ef36fd6496ffcb201c5f0ade71d5e5b04a0a0 Mon Sep 17 00:00:00 2001 From: jaywcjlove <398188662@qq.com> Date: Thu, 6 Oct 2022 02:20:53 +0800 Subject: [PATCH] doc: update `react.md`. --- docs/quickreference.md | 12 +- docs/react.md | 311 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 315 insertions(+), 8 deletions(-) diff --git a/docs/quickreference.md b/docs/quickreference.md index 0c6643e..7e1b8e7 100644 --- a/docs/quickreference.md +++ b/docs/quickreference.md @@ -142,6 +142,8 @@ export const Student = ( ```jsx {1,4-5} ``` +代码行高亮可以和代码行号一起使用。 + ### Tooltips [鼠标移动到上面有提示](https://github.com/jaywcjlove/reference) _Tooltips 的提示内容_ @@ -180,11 +182,15 @@ export const Student = ( ### 代码行号 ```jsx showLineNumbers -export const Student = ( -
-); +export const Student =
学生
; +const school =
学校
; ``` +下面是 `Markdown` 代码示例 + +```markdown + ```jsx showLineNumbers +``` ### 内置类样式 diff --git a/docs/react.md b/docs/react.md index faac731..a7bb979 100644 --- a/docs/react.md +++ b/docs/react.md @@ -327,7 +327,7 @@ const Student = () => ( 从 `v16.2.0` 开始 `Fragment` 可用于返回多个子节点,而无需向 DOM 添加额外的包装节点。或者使用 `<>` 效果是一样的。 -```jsx +```jsx {2,5} const Student = () => ( <> @@ -340,7 +340,7 @@ const Student = () => ( ### 返回字符串 -```jsx +```jsx {2} render() { return 'Look ma, no spans!'; } @@ -1011,12 +1011,313 @@ Menu.Item = ({ children }) => ( ``` -生命周期 ---- - Hooks --- +### Hooks API 参考 + + +#### 基础 Hook + +方法 | 描述 +:- | - +`useState` | 返回一个 `state`,更新 `state` 的函数 [#](https://zh-hans.reactjs.org/docs/hooks-reference.html#usestate) +`useEffect` | 可能有副作用代码的函数 [#](https://zh-hans.reactjs.org/docs/hooks-reference.html#useeffect) +`useContext` | 接收并返回该 `context` 的当前值 [#](https://zh-hans.reactjs.org/docs/hooks-reference.html#usecontext) + +#### 额外的 Hook + +方法 | 描述 +:- | - +`useReducer` | `useState` 的替代方案 [#](https://zh-hans.reactjs.org/docs/hooks-reference.html#usestate) +`useCallback` | 返回一个回调函数 [#](https://zh-hans.reactjs.org/docs/hooks-reference.html#usecallback) +`useMemo` | 返回一个 [memoized](https://en.wikipedia.org/wiki/Memoization) 值[#](https://zh-hans.reactjs.org/docs/hooks-reference.html#usememo) +`useRef` | 返回一个可变的 `ref` 对象 [#](https://zh-hans.reactjs.org/docs/hooks-reference.html#useref) +`useImperativeHandle` | 暴露给父组件的实例值 [#](https://zh-hans.reactjs.org/docs/hooks-reference.html#useimperativehandle) +`useLayoutEffect` | DOM 变更后同步调用函数 [#](https://zh-hans.reactjs.org/docs/hooks-reference.html#uselayouteffect) +`useDebugValue` | 开发者工具中显示标签 [#](https://zh-hans.reactjs.org/docs/hooks-reference.html#usedebugvalue) +`useDeferredValue` | 接受并返回该值的新副本 [#](https://zh-hans.reactjs.org/docs/hooks-reference.html#usedeferredvalue) +`useTransition` | 过渡任务的等待状态 [#](https://zh-hans.reactjs.org/docs/hooks-reference.html#usetransition) +`useId` | 用于生成唯一 ID [#](https://zh-hans.reactjs.org/docs/hooks-reference.html#useid) + +#### Library Hooks + +方法 | 描述 +:- | - +`useSyncExternalStore` | 读取和订阅外部数据源 [#](https://zh-hans.reactjs.org/docs/hooks-reference.html#usesyncexternalstore) +`useInsertionEffect` | DOM 突变之前 同步触发 [#](https://zh-hans.reactjs.org/docs/hooks-reference.html#usesyncexternalstore) + +### 函数式更新 + + +```jsx +function Counter({ initialCount }) { + const [count, setCount] = useState(initialCount); + return ( + <> + Count: {count} + + + + ); +} +``` + +### useRef + +```jsx +function TextInputWithFocusButton() { + const $input = useRef(null); + const onButtonClick = () => { + $input.current.focus(); + }; + return ( + <> + + + + ); +} +``` + +`current` 指向已挂载到 DOM 上的文本输入元素 + +### useImperativeHandle + +```jsx +function FancyInput(props, ref) { + const inputRef = useRef(); + useImperativeHandle(ref, () => ({ + focus: () => { + inputRef.current.focus(); + } + })); + return ; +} +FancyInput = forwardRef(FancyInput); +``` + +父组件使用 + +```jsx + +inputRef.current.focus() +``` + +### useEffect + +```jsx +useEffect(() => { + const subs = props.source.subscribe(); + return () => { + subs.unsubscribe(); + }; +}, [props.source]); +``` + +### useCallback + +```jsx +const memoizedCallback = useCallback( + () => { + doSomething(a, b); + }, + [a, b], +); +``` + +### useMemo + +```jsx +const memoizedValue = useMemo( + () => { + return computeExpensiveValue(a, b) + }, + [a, b] +); +``` + +### useId + +```jsx +function Checkbox() { + const id = useId(); + return ( + <> + + + + ); +}; +``` + +用于生成跨服务端和客户端稳定的唯一 `ID` 的同时避免 `hydration` 不匹配 + +### useDebugValue + +```jsx +function useFriendStatus(friendID) { + const [ + isOnline, setIsOnline + ] = useState(null); + // ... + // 在开发者工具中的这个 Hook 旁边显示标签 + // e.g. "FriendStatus: Online" + useDebugValue( + isOnline ? 'Online' : 'Offline' + ); + return isOnline; +} +``` + + +不推荐你向每个自定义 `Hook` 添加 `debug` 值 + +### componentDidMount & componentWillUnmount + +```jsx +useEffect( + () => { + // componentDidMount + // 组件挂载时,可以在这里完成你的任务 + return () => { + // componentWillUnmount + // 卸载时执行,清除 effect + }; + }, + [ ] +); +``` + +这是一个类似 `class` 组件中 `componentDidMount` & `componentWillUnmount` 两个生命周期函数的写法。 + +生命周期 +--- + + +### 挂载 + + +方法 | 描述 +:- | - +`constructor` _(props)_ | 渲染前 [#](https://zh-hans.reactjs.org/docs/react-component.html#constructor) +`static getDerivedStateFromProps()` | 调用 `render` 方法之前调用 [#](https://zh-hans.reactjs.org/docs/react-component.html#static-getderivedstatefromprops) +`render()` | `class` 组件中唯一必须实现的方法 [#](https://reactjs.org/docs/react-component.html#render) +`componentDidMount()` | 在组件挂载后(插入 DOM 树中)立即调用 [#](https://reactjs.org/docs/react-component.html#componentdidmount) +`UNSAFE_componentWillMount()` | 在挂载之前被调用,建议使用 `constructor()` [#](https://zh-hans.reactjs.org/docs/react-component.html#unsafe_componentwillmount) + +在 `constructor()` 上设置初始状态。在 `componentDidMount()` 上添加 DOM 事件处理程序、计时器(等),然后在 `componentWillUnmount()` 上删除它们。 + +### 卸载 + +方法 | 描述 +:- | - +`componentWillUnmount()` | 在组件卸载及销毁之前直接调用 [#](https://zh-hans.reactjs.org/docs/react-component.html#componentwillunmount) + +### 过时 API + +过时方法 | 新方法 +:- | - +~~`componentWillMount()`~~ | `UNSAFE_componentWillMount()` [#](https://zh-hans.reactjs.org/docs/react-component.html#unsafe_componentwillmount) +~~`componentWillReceiveProps()`~~ | `UNSAFE_componentWillReceiveProps()` [#](https://zh-hans.reactjs.org/docs/react-component.html#unsafe_componentwillreceiveprops) +~~`componentWillUpdate()`~~ | `UNSAFE_componentWillUpdate()` [#](https://zh-hans.reactjs.org/docs/react-component.html#unsafe_componentwillupdate) + +17+ 之后不再支持,在 `17` 版本之后,只有新的 `UNSAFE_` 生命周期名称可以使用。 + +### 更新 + + +方法 | 描述 +:- | - +`static getDerivedStateFromProps(props, state)` | 调用 `render` 之前调用,在初始挂载及后续更新时都会被调用 [#](https://zh-hans.reactjs.org/docs/react-component.html#static-getderivedstatefromprops) +`shouldComponentUpdate(nextProps, nextState)` | 如果返回 `false`,则跳过 `render()` [#](https://zh-hans.reactjs.org/docs/react-component.html#static-getderivedstatefromprops) +`render()` | 在不修改组件 `state` 的情况下,每次调用时都返回相同的结果 [#](https://zh-hans.reactjs.org/docs/react-component.html#render) +`getSnapshotBeforeUpdate()` | 在发生更改之前从 DOM 中捕获一些信息(例如,滚动位置) [#](https://zh-hans.reactjs.org/docs/react-component.html#getsnapshotbeforeupdate) +`componentDidUpdate()` | 这里使用 `setState()`,但记得比较 `props`。首次渲染不会执行此方法 [#](https://zh-hans.reactjs.org/docs/react-component.html#componentdidupdate) + +### 错误处理 + + +方法 | 描述 +:- | - +`static getDerivedStateFromError(error)` | 后代组件抛出错误后被调用,它将抛出的错误作为参数,并返回一个值以更新 `state` [#](https://zh-hans.reactjs.org/docs/react-component.html#static-getderivedstatefromerror) +`componentDidCatch(error, info)` | 在后代组件抛出错误后被调用,会在“提交”阶段被调用,因此允许执行副作用 [#](https://zh-hans.reactjs.org/docs/react-component.html#componentdidcatch) + +### render() + +```jsx {2} +class Welcome extends React.Component { + render() { + return

Hello, {this.props.name}

; + } +} +``` + +### constructor() + +```jsx {1} +constructor(props) { + super(props); + // 不要在这里调用 this.setState() + this.state = { counter: 0 }; + this.handleClick = this.handleClick.bind(this); +} +``` + +### static getDerivedStateFromError() + + +```jsx {7,13} +class ErrorBoundary extends React.Component { + constructor(props) { + super(props); + this.state = { hasError: false }; + } + + static getDerivedStateFromError(error) { + // 更新 state 使下一次渲染可以显降级 UI + return { hasError: true }; + } + + render() { + if (this.state.hasError) { + // 你可以渲染任何自定义的降级 UI + return

Something went wrong.

; + } + + return this.props.children; + } +} +``` + +### componentDidUpdate() + +```jsx {1} +componentDidUpdate(prevProps) { + // 典型用法(不要忘记比较 props): + if (this.props.uid !== prevProps.uid) { + this.fetchData(this.props.uid); + } +} +``` + +### getSnapshotBeforeUpdate() + +```jsx +getSnapshotBeforeUpdate(prevProps, prevState) { + // 我们是否在 list 中添加新的 items ? + // 捕获滚动​​位置以便我们稍后调整滚动位置。 + if (prevProps.list.length < this.props.list.length) { + const list = this.listRef.current; + return list.scrollHeight - list.scrollTop; + } + return null; +} +``` PropTypes 属性类型检查 ---