From 363e4d3e35576e0d42276f098a6289ab4ed4879f Mon Sep 17 00:00:00 2001 From: jaywcjlove Date: Wed, 5 Oct 2022 18:21:30 +0000 Subject: [PATCH] doc: update `react.md`. 864ef36fd6496ffcb201c5f0ade71d5e5b04a0a0 --- docs/quickreference.html | 9 +- docs/react.html | 401 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 402 insertions(+), 8 deletions(-) diff --git a/docs/quickreference.html b/docs/quickreference.html index 784d23f9..92e230d4 100644 --- a/docs/quickreference.html +++ b/docs/quickreference.html @@ -145,6 +145,7 @@

上面 {1,4-5} 行代码高亮,下面是 Markdown 代码示例

  ```jsx {1,4-5}
 
+

代码行高亮可以和代码行号一起使用。

Tooltips

鼠标移动到上面有提示Tooltips 的提示内容

添加注释配置 <!--rehype:tooltips--> 添加一个 Tooltips 提示。

@@ -182,9 +183,11 @@

列表添加 <!--rehype:className=shortcuts--> 样式类,展示快捷键样式。

代码行号

-
export const Student = (
-  <div className="Student"></div>
-);
+
export const Student = <div>学生</div>;
+const school = <div>学校</div>;
+
+

下面是 Markdown 代码示例

+
  ```jsx showLineNumbers
 

内置类样式

diff --git a/docs/react.html b/docs/react.html index d6f0325c..dc316845 100644 --- a/docs/react.html +++ b/docs/react.html @@ -269,16 +269,16 @@

v16.2.0 开始 Fragment 可用于返回多个子节点,而无需向 DOM 添加额外的包装节点。或者使用 <></> 效果是一样的。

const Student = () => (
-  <>
+  <>
     <Avatar src="./demo.jpg" />
     <Profile username="name" />
-  </>
+  </>
 );
 

查看: Fragments & strings

返回字符串

render() {
-  return 'Look ma, no spans!';
+  return 'Look ma, no spans!';
 }
 

您可以只返回一个字符串。查看: Fragments & strings

@@ -852,9 +852,400 @@ <Menu.Item>菜单二</Menu.Item> <Menu> +

Hooks

+

Hooks API 参考

+ +

基础 Hook

+ + + + + + + + + + + + + + + + + + + + + +
方法描述
useState返回一个 state,更新 state 的函数 #
useEffect可能有副作用代码的函数 #
useContext接收并返回该 context 的当前值 #
+

额外的 Hook

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
方法描述
useReduceruseState 的替代方案 #
useCallback返回一个回调函数 #
useMemo返回一个 memoized#
useRef返回一个可变的 ref 对象 #
useImperativeHandle暴露给父组件的实例值 #
useLayoutEffectDOM 变更后同步调用函数 #
useDebugValue开发者工具中显示标签 #
useDeferredValue接受并返回该值的新副本 #
useTransition过渡任务的等待状态 #
useId用于生成唯一 ID #
+

Library Hooks

+ + + + + + + + + + + + + + + + + +
方法描述
useSyncExternalStore读取和订阅外部数据源 #
useInsertionEffectDOM 突变之前 同步触发 #
+

函数式更新

+ +
function Counter({ initialCount }) {
+  const [count, setCount] = useState(initialCount);
+  return (
+    <>
+      Count: {count} <button onClick={() => setCount(initialCount)}>Reset</button>
+      <button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>
+      <button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
+    </>
+  );
+}
+
+

useRef

+
function TextInputWithFocusButton() {
+  const $input = useRef(null);
+  const onButtonClick = () => {
+    $input.current.focus();
+  };
+  return (
+    <>
+      <input ref={$input} type="text" />
+      <button onClick={onButtonClick}>
+        聚焦输入
+      </button>
+    </>
+  );
+}
+
+

current 指向已挂载到 DOM 上的文本输入元素

+

useImperativeHandle

+
function FancyInput(props, ref) {
+  const inputRef = useRef();
+  useImperativeHandle(ref, () => ({
+    focus: () => {
+      inputRef.current.focus();
+    }
+  }));
+  return <input ref={inputRef} />;
+}
+FancyInput = forwardRef(FancyInput);
+
+

父组件使用

+
<FancyInput ref={inputRef} />
+inputRef.current.focus()
+
+

useEffect

+
useEffect(() => {
+  const subs = props.source.subscribe();
+  return () => {
+    subs.unsubscribe();
+  };
+}, [props.source]);
+
+

useCallback

+
const memoizedCallback = useCallback(
+  () => {
+    doSomething(a, b);
+  },
+  [a, b],
+);
+
+

useMemo

+
const memoizedValue = useMemo(
+  () => {
+    return computeExpensiveValue(a, b)
+  },
+  [a, b]
+);
+
+

useId

+
function Checkbox() {
+  const id = useId();
+  return (
+    <>
+      <label htmlFor={id}>
+        你喜欢React吗?
+      </label>
+      <input id={id} type="checkbox" />
+    </>
+  );
+};
+
+

用于生成跨服务端和客户端稳定的唯一 ID 的同时避免 hydration 不匹配

+

useDebugValue

+
function useFriendStatus(friendID) {
+  const [
+    isOnline, setIsOnline
+  ] = useState(null);
+  // ...
+  // 在开发者工具中的这个 Hook 旁边显示标签
+  // e.g. "FriendStatus: Online"
+  useDebugValue(
+    isOnline ? 'Online' : 'Offline'
+  );
+  return isOnline;
+}
+
+ +

不推荐你向每个自定义 Hook 添加 debug

+

componentDidMount & componentWillUnmount

+
useEffect(
+  () => {
+    // componentDidMount
+    // 组件挂载时,可以在这里完成你的任务
+    return () => {
+      // componentWillUnmount
+      // 卸载时执行,清除 effect
+    };
+  },
+  [ ]
+);
+
+

这是一个类似 class 组件中 componentDidMount & componentWillUnmount 两个生命周期函数的写法。

生命周期

-

Hooks

-

PropTypes 属性类型检查

+ +

挂载

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
方法描述
constructor (props)渲染前 #
static getDerivedStateFromProps()调用 render 方法之前调用 #
render()class 组件中唯一必须实现的方法 #
componentDidMount()在组件挂载后(插入 DOM 树中)立即调用 #
UNSAFE_componentWillMount()在挂载之前被调用,建议使用 constructor() #
+

constructor() 上设置初始状态。在 componentDidMount() 上添加 DOM 事件处理程序、计时器(等),然后在 componentWillUnmount() 上删除它们。

+

卸载

+ + + + + + + + + + + + + +
方法描述
componentWillUnmount()在组件卸载及销毁之前直接调用 #
+

过时 API

+ + + + + + + + + + + + + + + + + + + + + +
过时方法新方法
componentWillMount()UNSAFE_componentWillMount() #
componentWillReceiveProps()UNSAFE_componentWillReceiveProps() #
componentWillUpdate()UNSAFE_componentWillUpdate() #
+

17+ 之后不再支持,在 17 版本之后,只有新的 UNSAFE_ 生命周期名称可以使用。

+

更新

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
方法描述
static getDerivedStateFromProps(props, state)调用 render 之前调用,在初始挂载及后续更新时都会被调用 #
shouldComponentUpdate(nextProps, nextState)如果返回 false,则跳过 render() #
render()在不修改组件 state 的情况下,每次调用时都返回相同的结果 #
getSnapshotBeforeUpdate()在发生更改之前从 DOM 中捕获一些信息(例如,滚动位置) #
componentDidUpdate()这里使用 setState(),但记得比较 props。首次渲染不会执行此方法 #
+

错误处理

+ + + + + + + + + + + + + + + + + + +
方法描述
static getDerivedStateFromError(error)后代组件抛出错误后被调用,它将抛出的错误作为参数,并返回一个值以更新 state #
componentDidCatch(error, info)在后代组件抛出错误后被调用,会在“提交”阶段被调用,因此允许执行副作用 #
+

render()

+
class Welcome extends React.Component {
+  render() {
+    return <h1>Hello, {this.props.name}</h1>;
+  }
+}
+
+

constructor()

+
constructor(props) {
+  super(props);
+  // 不要在这里调用 this.setState()
+  this.state = { counter: 0 };
+  this.handleClick = this.handleClick.bind(this);
+}
+
+

static getDerivedStateFromError()

+ +
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 <h1>Something went wrong.</h1>;
+    }
+
+    return this.props.children;
+  }
+}
+
+

componentDidUpdate()

+
componentDidUpdate(prevProps) {
+  // 典型用法(不要忘记比较 props):
+  if (this.props.uid !== prevProps.uid) {
+    this.fetchData(this.props.uid);
+  }
+}
+
+

getSnapshotBeforeUpdate()

+
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 属性类型检查

PropTypes

import PropTypes from 'prop-types'