管理共享状态的简单方法 反应
在反应上建造 钩子 API
灵感来自 原子单位 试剂.cljs
说明
react-atom 提供一种非常简单的方式来管理 React 中的状态, 对于全局应用程序状态和当地组件状态: QQAtoms.
让你的状态 Atom数字 :
import { Atom } from "@dbeining/react-atom";
const appState = Atom.of({
color: "blue",
userId: 1
});
读取状态为 deref
你不能检查 Atom 你必须直接声明 deref像这样
import { deref } from "@dbeining/react-atom";
const { color } = deref(appState);
更新状态 swap
你不能修改一个 Atom 直接说 更新状态的主要途径是: swap。这里是它的呼号:
function swap<S>(atom: Atom<S>, updateFn: (state: S) => S): void;
updateFn 适用于 atom'状态和返回值被设定为 atom新状态 只有两个简单的规则 updateFn数字 :
- 它必须返回与上一个状态相同的类型/接口的值
- 它不能改变 以前的状态
说明一下,我们如何更新 appState颜色 :
import { swap } from "@dbeining/react-atom";
const setColor = color =>
swap(appState, state => ({
...state,
color: color
}));
注意我们 updateFn 实值 传播将旧状态置入新对象后再压倒 color这很容易遵守 updateFn。 。 。 .
副作用吗? 刚刚使用 swap
你不需要做任何特别的 管理副作用。 照常写你的IO相关逻辑,然后打电话 swap 当你得到了你需要的。 例如:
const saveColor = async color => {
const { userId } = deref(appState);
const theme = await post(`/api/user/${userId}/theme`, { color });
swap(appState, state => ({ ...state, color: theme.color }));
};
在状态变化上与 QQ 重交组件useAtomQQ 自定义反应钩
useAtom 是一个 自定义反应钩它做两件事:
- 返回原子的当前状态(如
deref),以及 - 将您的组件订阅到原子上, 这样它每次状态变化时都会重递
看起来是这样的:
export function ColorReporter(props) {
const { color, userId } = useAtom(appState);
return (
<div>
<p>
User {userId} has selected {color}
</p>
{/* `useAtom` hook will trigger a re-render on `swap` */}
<button onClick={() => swap(appState, setRandomColor)}>Change Color</button>
</div>
);
}
Nota Bene:您也可以使用选择器通过使用
options.select参数. 读取文件 详细情况.
为什么用 react-atom? 吗?
😌 微小 API / 学习曲线
`Atom.of'、`使用Atom'和`swap'将涵盖绝大多数的使用案例.
🚫 没有锅炉板,只有可预测的状态管理
减速器? 行动? 汤克斯? 萨加斯? 不,只是"扫荡(原子,新国家)".
🎵 表演部件渲染训练
这个useAtom钩子接受可选select函数让组件订阅计算状态。 这意味着该组件只有在返回的值从select变化.
😬 React.useState 玩不开心 React.memo
useState很酷,直到你意识到,在大多数情况下,它迫使你通过每个渲染处的道具传递新的函数实例,因为你通常需要包接setState函数。 这很难利用React.memo。例如:-- -- . .function Awkwardddd(props) { const [name, setName] = useState(""); const [bigState, setBigState] = useState({ ...useYourImagination }); const updateName = evt => setName(evt.target.value); const handleDidComplete = val => setBigState({ ...bigState, inner: val }); return ( <> <input type="text" value={name} onChange={updateName} /> <ExpensiveButMemoized data={bigState} onComplete={handleDidComplete} /> </> ); }每一次
input火灾onChange, (中文(简体) ),ExpensiveButMemoized必须重新投降,因为handleDidComplete与最后通过的判决不完全相同.反应文件承认这很尴尬 建议利用背景来研究,因为 替代品是超曲折的。 。 。 .
与
react-atom这个问题根本不存在 您可以在组件外定义您的更新功能, 以便它们具有优异的稳定性 .const state = Atom.of({ name, bigState: { ...useYourImagination } }); const updateName = ({ target }) => swap(state, prev => ({ ...prev, name: target.value })); const handleDidComplete = val => swap(state, prev => ({ ...prev, bigState: { ...prev.bigState, inner: val } })); function SoSmoooooth(props) { const { name, bigState } = useAtom(state); return ( <> <input type="text" value={name} onChange={updateName} /> <ExpensiveButMemoized data={bigState} onComplete={handleDidComplete} /> </> ); }
TS 翻译 第一等类型脚本支持
react-atom 以 TypeScript 写成,这样每个版本都会以正确,高质量的打字方式发布.
⚛️ 拥抱与虎克的未来
虎克会做的class部件及其种类(更高级部件、成品相干部件和随子功能相干部件)已过时.react-atom使得管理共享状态变得容易,只有函数组件和钩子.
安装
npm i -S @dbeining/react-atom
依赖关系
react-atom 有一个捆绑的依赖, @libre/原子语,它提供了原子数据类型。 其全部再出口自 @dbeining/atom文档 这里。 。 。 .
react-atom 也有两个 peerDependencies,即:, react@^16.8.0 财务报告和审定财务报表 react-dom@^16.8.0包含Hooks API.
文档
代码示例 react-atom 行动
点击代码样本
import React from "react";
import ReactDOM from "react-dom";
import { Atom, useAtom, swap } from "@dbeining/react-atom";
//------------------------ APP STATE ------------------------------//
const stateAtom = Atom.of({
count: 0,
text: "",
data: {
// ...just imagine
}
});
//------------------------ EFFECTS ------------------------------//
const increment = () =>
swap(stateAtom, state => ({
...state,
count: state.count + 1
}));
const decrement = () =>
swap(stateAtom, state => ({
...state,
count: state.count - 1
}));
const updateText = evt =>
swap(stateAtom, state => ({
...state,
text: evt.target.value
}));
const loadSomething = () =>
fetch("https://jsonplaceholder.typicode.com/todos/1")
.then(res => res.json())
.then(data => swap(stateAtom, state => ({ ...state, data })))
.catch(console.error);
//------------------------ COMPONENT ------------------------------//
export const App = () => {
const { count, data, text } = useAtom(stateAtom);
return (
<div>
<p>Count: {count}</p>
<p>Text: {text}</p>
<button onClick={increment}>Moar</button>
<button onClick={decrement}>Less</button>
<button onClick={loadSomething}>Load Data</button>
<input type="text" onChange={updateText} value={text} />
<p>{JSON.stringify(data, null, " ")}</p>
</div>
);
};
ReactDOM.render(<App />, document.getElementById("root"));
游戏 react-atom 在代码Sandbox中
你可以玩游戏 react-atom 立即在下列链接中没有设置 :
| Java 脚本沙盒 | 类型脚本沙盒 |
|---|---|
贡献/反馈
如果您有任何问题和建议,请开始讨论 改进/特性,或想要提交错误修正的PR(请包括 (如果适用的话).