diff --git a/docs/fea/react/pattern.md b/docs/fea/react/pattern.md
index fcc711a..5f99073 100644
--- a/docs/fea/react/pattern.md
+++ b/docs/fea/react/pattern.md
@@ -14,14 +14,14 @@ group:
世界知名三大框架之一,我认为热度目前为首吧
-### 设计原则
+### iPhone 上的秒表
+
+设计组件的几个原则:
1. 保持接口小,props 数量要少
2. 根据数据边界划分组件,充分利用组合
3. 把 state 往上层组件提取,让下层组件只需要实现为纯函数
-举例,iPhone 上的秒表:
-
```jsx
import React, { useState } from 'react';
@@ -40,7 +40,7 @@ const MajorClock = ({ ms = 0 }) => {
return result;
};
- return
-
-
+
+
+
);
} else {
return (
-
-
-
+
+
+
);
}
@@ -89,9 +112,9 @@ export default class StopWatch extends React.Component {
state = {
isStarted: false,
- startTime: null,
- currentTime: null,
- spilts: [],
+ startTime: 0,
+ currentTime: 0,
+ splits: [],
};
render() {
@@ -99,6 +122,7 @@ export default class StopWatch extends React.Component {
return (
+ 秒表
我是一个无状态组件;
+ }
+}
+
+// 函数组件
+const Demo = React.memo(() =>
我是一个无状态组件
);
+```
+
## 高阶组件(HOC)
高阶组件的几个原则:
@@ -147,28 +187,158 @@ export default class StopWatch extends React.Component {
2. 结果必须是一个新的 React 组件,新组件的 JSX 部分包含作为参数的组件
3. 一般需要把传给自己的 props 转手传递给作为参数的组件
+> 一般会带 with 前缀
+
+### 普通用法
+
```jsx
import React from 'react';
-class Demo extends React.Component {
- constructor() {
- super();
- }
+const getUserId = () => {
+ return true;
+};
- render() {
- const { store } = this.props;
- return
艹 {store}
;
- }
-}
+const LoginBtn = () => {
+ return
退出登录
;
+};
-const withFuckU = (Component) => {
+const ShoppingCar = () => {
+ return
购物车
;
+};
+
+const withLogin = (Component) => {
const NewComponent = (props) => {
- return
;
+ if (getUserId()) {
+ return
;
+ } else {
+ return null;
+ }
};
return NewComponent;
};
-export default withFuckU(Demo);
+const LoginButton = withLogin(LoginBtn);
+const LoginCar = withLogin(ShoppingCar);
+
+export default () => (
+
+
+
+
+);
+```
+
+### 高级用法
+
+借鉴上文的 withLogin,根据用户是否选择登录渲染合适的组件:
+
+```js
+const withLoginAndLogout = (ComponentForLogin, ComponentForLogout) => {
+ const NewComponent = (props) => {
+ if (getUserId()) {
+ return
;
+ } else {
+ return
;
+ }
+ };
+ return NewComponent;
+};
+
+const LoginBtn = () => {
+ return
登录
;
+};
+
+const LogoutBtn = () => {
+ return
退出登录
;
+};
+
+// 通过条件判断 退出(登录)按钮
+const TopButtons = withLoginAndLogout(LogoutBtn, LoginBtn);
+```
+
+### 链式调用
+
+```js
+// 示例 1
+const SuperX = withMethod3(withMethod2(withMethod1(x)));
+
+// 示例 2
+const compose = (...funcs) {
+ if (funcs.length === 0) return arg => arg
+
+ if (funcs.length === 1) return funcs[0]
+
+ return funcs.reduce((a, b) => (...args) => a(b(...args)))
+}
+
+const hoc = compose(withMethod3, withMethod2, withMethod1)
+const SuperX = hoc(x)
+```
+
+## render props 模式
+
+示例:
+
+```js
+const Auth = (props) => {
+ const userName = getUserName();
+
+ if (userName) {
+ const allProps = { userName, ...props };
+ return
{props.login(allProps)};
+ } else {
+
{props.nologin(props)};
+ }
+};
+
+// 调用
+
Hello {userName}
}
+ nologin={() => Please login
}
+/>;
+```
+
+## 提供者模式
+
+```jsx
+import React from 'react';
+
+const ThemeContext = React.createContext();
+const ThemeProvider = ThemeContext.Provider;
+const ThemeConsumer = ThemeContext.Consumer;
+
+const Title = (props, context) => {
+ return (
+
+ {(theme) => {props.children}
}
+
+ );
+};
+
+const Paragraph = (props, context) => {
+ return (
+
+ {(theme) => {props.children}
}
+
+ );
+};
+
+const Page = () => {
+ return (
+
+ );
+};
+
+export default (props, context) => {
+ return (
+
+
+
+ );
+};
```
## 参考资料