Unstated Next readme 的中文翻译
前言
这个库的作者希望使用 React 内置 API ,直接实现状态管理的功能。看完这个库的说明后,没有想到代码可以这个玩。短短几行代码,仅仅使用 React Hooks ,就实现了状态管理的功能。
看完之后,第一想法就是翻译成中文,分享给其他人。提交 Pull Request 后,库作者将我的翻译合并了。同时作者欢迎将 README 翻译成其他语言,以下是全部翻译内容,不妥之处欢迎指正或 Pull Request.
Unstated Next
永远不必再考虑 React 状态管理了,仅仅 200 字节的状态管理解决方案。
- React Hooks React Hooks 用做你所有的状态管理。
- ~200 bytes min+gz.
- 熟悉的 API 仅仅使用了 React,没有依赖第三方库。
- 最小 API 只需 5 分钟学习。
- TypeScript 编写 推断代码更容易,易于编写 React 代码。
但是,最重要的问题是:这比 Redux 更好吗? 答案可能是。
- 它更小。 比 Redux 小 40 倍。
- 它更快。 组件性能问题。
- 它更容易学习。 你必须已经知道 React Hooks 和 Context 。只需使用它们,它们就会嗨起来。
- 更容易集成。 一次集成一个组件,并且轻松与其他 React 库集成。
- 它更容易测试。 测试 reducers 纯属浪费你的时间,这个库使你更容易测试 React 组件。
- 它更容易进行类型检查。 旨在使你的大多数类型可推断。
- 它是最小的。 仅仅使用了 React 。
你自己看着办吧!
查看 Unstated 迁移手册 →
安装
npm install --save unstated-next
Example
import React, { useState } from "react"
import { createContainer } from "unstated-next"
import { render } from "react-dom"
function useCounter() {
let [count, setCount] = useState(0)
let decrement = () => setCount(count - 1)
let increment = () => setCount(count + 1)
return { count, decrement, increment }
}
let Counter = createContainer(useCounter)
function CounterDisplay() {
let counter = Counter.useContainer()
return (
<div>
<button onClick={counter.decrement}>-</button>
<span>{counter.count}</span>
<button onClick={counter.increment}>+</button>
</div>
)
}
function App() {
return (
<Counter.Provider>
<CounterDisplay />
<CounterDisplay />
</Counter.Provider>
)
}
render(<App />, document.getElementById("root"))
API
createContainer(useHook)
import { createContainer } from "unstated-next"
function useCustomHook() {
let [value, setInput] = useState()
let onChange = e => setValue(e.currentTarget.value)
return { value, onChange }
}
let Container = createContainer(useCustomHook)
// Container === { Provider, useContainer }
<Container.Provider>
function ParentComponent() {
return (
<Container.Provider>
<ChildComponent />
</Container.Provider>
)
}
Container.useContainer()
function ChildComponent() {
let input = Container.useContainer()
return <input value={input.value} onChange={input.onChange} />
}
useContainer(Container)
import { useContainer } from "unstated-next"
function ChildComponent() {
let input = useContainer(Container)
return <input value={input.value} onChange={input.onChange} />
}
指南
如果你以前从未使用过 React Hooks,我不建议你往下看,请先阅读 [React 官网的 React Hooks 文档](https://reactjs.org/docs/hooks-intro.html)。
首先,使用 React Hooks,你可以创建这样一个组件:
function CounterDisplay() {
let [count, setCount] = useState(0)
let decrement = () => setCount(count - 1)
let increment = () => setCount(count + 1)
return (
<div>
<button onClick={decrement}>-</button>
<p>You clicked {count} times</p>
<button onClick={increment}>+</button>
</div>
)
}
然后,如果你想共享组件的逻辑,你可以把它写在组件外面,自定义一个 hook:
function useCounter() {
let [count, setCount] = useState(0)
let decrement = () => setCount(count - 1)
let increment = () => setCount(count + 1)
return { count, decrement, increment }
}
function CounterDisplay() {
let counter = useCounter()
return (
<div>