Title Text
函数式编程范式
-
输出完全取决于参数
-
无副作用 (Immutable)
-
关注想得到的结果,而不是过程(声明式)
}
纯函数
输出完全取决于参数
✅
❌
(showButton, buttonText) =>
<div>
{showButton &&
<button>
{buttonText}
</button>}
</div>
(showButton) =>
<div>
{showButton &&
<button>
{localStorage
.getItem(‘buttonText’)}
</button>}
</div>
无副作用
✅
❌
const addItem = (itemList, item) => {
return [...itemList, item]
}
const addItem = (itemList, item) => {
itemList.push(item);
return itemList;
}
const getMessage = async () => {
const message =
await get('/api/message');
return message;
}
声明式
描述我想要的结果是什么
命令式
描述具体怎么做
(showButton) =>
<div>
{showButton && <button>click</button>}
</div>
(showButton, $container) => {
if (showButton) {
$container
.append($('<button>click<button>'));
} else {
$container
.remove('button');
}
}
const getFields = (items, fieldName) => items
.filter(item => item[fieldName])
.sort((a, b) => a[fieldName] - b[fieldName])
.map(item => item[fieldName])
const getFields = (items, fieldName) => {
const ret = [];
for (let i = 0; i < item.length; i++) {
if (items[i][fieldName]) {
ret.push(items[i][fieldName])
}
}
return ret;
}
为什么需要纯函数
- 输出完全取决于参数:可预测,不会被别人影响
- 无副作用:不会影响别人
- 以结果为导向,步骤清晰,容易理解
- 容易测试
- 可缓存
简单的 React 组件是纯函数
// https://reactjs.org/docs/components-and-props.html
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
复杂的 React 组件不是...
- 内部 state
- 副作用 (发送请求,触发事件)
- PureComponent ≠ pure function
Redux:“纯化”了 React
- 取消内部状态,输出只由参数(props)决定
- 状态的变化(reducer)也是纯函数
- 统一管理副作用(thunk)
Redux State
UI
Reducer
Actions
pure
pure
pure
impure
Redux 的理想模型
- 所有数据存在 Redux 的 state 里
- UI 完全由 Redux state 决定(是关于 state 的纯函数)
- UI 发送事件(action)驱动 Redux state 更新
- 逻辑独立于 UI
Redux 的理想模型
- React 组件只包含渲染逻辑 + 事件回调 (hooks, event handlers)。类比 handlebars
- Action 相当于 event,描述发生了什么,类比 dom event
- Reducer 包含真正的逻辑
- Selector 负责数据的转换与组装(同样是纯函数)
现实是...
UI 数据来源与生命周期:
Redux state (每次页面刷新)
Component state (每次组件加载)
localStorage / sessionStorage (永久 / 浏览器打开)
cookie (取决于后端设置)
URL (每次 URL 改变)
History state (每次 URL 改变)
deck
By lukeupup
deck
- 198