From 60c0fbcc8ac23fc8249df623f924deb9d05464c0 Mon Sep 17 00:00:00 2001
From: ymrdf <837856276@qq.com>
Date: Fri, 18 Jan 2019 11:13:06 +0800
Subject: [PATCH] docs(docs,README): add Chinese Readme document
---
README.md | 2 +
docs/zh-cn.md | 473 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 475 insertions(+)
create mode 100644 docs/zh-cn.md
diff --git a/README.md b/README.md
index 72a22b5..8a11cd8 100644
--- a/README.md
+++ b/README.md
@@ -8,6 +8,8 @@
> State so simple, it goes without saying
+[中文](./docs/zh-cn.md)
+
## Installation
```sh
diff --git a/docs/zh-cn.md b/docs/zh-cn.md
new file mode 100644
index 0000000..ebc8e7a
--- /dev/null
+++ b/docs/zh-cn.md
@@ -0,0 +1,473 @@
+
+
+

+
+
+
+# Unstated
+
+> 不消说,状态管理就是如此简单!
+
+[ENGLISH](../README.md)
+
+## 安装
+
+```sh
+yarn add unstated
+```
+
+## 例子
+
+```jsx
+// @flow
+import React from 'react';
+import { render } from 'react-dom';
+import { Provider, Subscribe, Container } from 'unstated';
+
+type CounterState = {
+ count: number
+};
+
+class CounterContainer extends Container {
+ state = {
+ count: 0
+ };
+
+ increment() {
+ this.setState({ count: this.state.count + 1 });
+ }
+
+ decrement() {
+ this.setState({ count: this.state.count - 1 });
+ }
+}
+
+function Counter() {
+ return (
+
+ {counter => (
+
+
+ {counter.state.count}
+
+
+ )}
+
+ );
+}
+
+render(
+
+
+ ,
+ document.getElementById('root')
+);
+```
+
+更多例子, 请看 `example/` 文件夹.
+
+## 用户说
+
+
+ "Unstated 是状态管理工具中的一股清流啊!俺昨天用它重写了整个项目!"
+
+ Sindre Sorhus
+
+
+
+ "当人们喊着大部分时候你都不需要用redux时,他们实际上在说你需要Unstated。
setState用起来像嗑了药一样爽啊!"
+
+ Ken Wheeler (obviously)
+
+
+## Guide
+
+如果你和我一样对所有React状态管理模式感到不爽,想更React,不折腾一些令人发狂的架构和方法论。
+
+所以,你开始想:React组件的state API挺好的呀!容易理解,上手快:
+
+```jsx
+class Counter extends React.Component {
+ state = { count: 0 };
+ increment = () => {
+ this.setState({ count: this.state.count + 1 });
+ };
+ decrement = () => {
+ this.setState({ count: this.state.count - 1 });
+ };
+ render() {
+ return (
+
+ {this.state.count}
+
+
+
+ );
+ }
+}
+```
+
+做为一个React新手你可能不能准确的知道所有细节,但你可以很快就弄明白大体功能是怎么回事。
+
+
+唯一的问题是,我们不能方便的共享这个state。因为React组件被设计成为具有独立性。
+
+如果我们能在多组件共享数据时使用React组件的state API就好啦!!
+
+但是要怎么在多个组件之间共享数据呢?当然是用"context"啦!
+
+> **Note:** 这是新的 `React.createContext` API 节选。
+> [described in this RFC](https://github.com/reactjs/rfcs/blob/master/text/0002-new-version-of-context.md).
+
+```jsx
+const Amount = React.createContext(1);
+
+class Counter extends React.Component {
+ state = { count: 0 };
+ increment = amount => { this.setState({ count: this.state.count + amount }); };
+ decrement = amount => { this.setState({ count: this.state.count - amount }); };
+ render() {
+ return (
+
+ {amount => (
+
+ {this.state.count}
+
+
+
+ )}
+
+ );
+ }
+}
+
+class AmountAdjuster extends React.Component {
+ state = { amount: 0 };
+ handleChange = event => {
+ this.setState({
+ amount: parseInt(event.currentTarget.value, 10)
+ });
+ };
+ render() {
+ return (
+
+
+ {this.props.children}
+
+
+
+ );
+ }
+}
+
+render(
+
+
+
+);
+```
+
+这已经挺棒了。只要你对React思想稍微有点见解,就会明白这种写法语义明确可预测性强。
+
+但我们现在要从这里出发,让事情更棒!
+
+### Unstated 简介
+
+以上就是Unstated怎么来的。
+
+Unstated就是建立在React组件和context API之上的。
+
+它有三部分:
+
+##### `Container`
+
+存放状态和逻辑的地方!
+
+`Container` 是一个特别像`React.Component` 的类,但是只拥有state相关的部分: `this.state` 和
+`this.setState`.
+
+
+```js
+class CounterContainer extends Container {
+ state = { count: 0 };
+ increment = () => {
+ this.setState({ count: this.state.count + 1 });
+ };
+ decrement = () => {
+ this.setState({ count: this.state.count - 1 });
+ };
+}
+```
+
+`Container` 还在幕后做一些发送事件,以使我们的APP可以监听更新的事情。执行 `setState` 会引发重新渲染。注意别直接更改this.state, 直接更改不会重新渲染。
+
+
+###### `setState()`
+
+`Container` 的 `setState()` 和React的`setState()`基本一样。
+
+```js
+class CounterContainer extends Container {
+ state = { count: 0 };
+ increment = () => {
+ this.setState(
+ state => {
+ return { count: state.count + 1 };
+ },
+ () => {
+ console.log('Updated!');
+ }
+ );
+ };
+}
+```
+
+它也是异步的,你使用它时要遵守和React一样的约定。
+
+**别设完state后立即从state里取值**
+
+```js
+class CounterContainer extends Container {
+ state = { count: 0 };
+ increment = () => {
+ this.setState({ count: 1 });
+ console.log(this.state.count); // 0
+ };
+}
+```
+
+**如果你在计算下一个state时用到前一个state,就用函数形式**
+
+```js
+class CounterContainer extends Container {
+ state = { count: 0 };
+ increment = () => {
+ this.setState(state => {
+ return { count: state.count + 1 };
+ });
+ };
+}
+```
+
+但是和React的`setState()`不一样的是, Unstated的`setState()`返回的是一个promise对象,所以你可以像下面这样使用`await`:
+
+```js
+class CounterContainer extends Container {
+ state = { count: 0 };
+ increment = async () => {
+ await this.setState({ count: 1 });
+ console.log(this.state.count); // 1
+ };
+}
+```
+
+Async 函数现在已经被[绝大多数现代浏览器](https://caniuse.com/#feat=async-functions)支持了,但是你也可以用[Babel](http://babeljs.io)将它解析成其它版本的JS以适配所有浏览器。
+
+##### ``
+
+另一快儿,我们须要把我们的state插入组件树中,以完成三项功能:
+* 当state改变时,重渲染我们的组件;
+* 依赖container中的state;
+* 调用container中的方法;
+
+为此,Unstated提供 `` 组件来让我们把container的类或实例传入组件树,而组件会接收到一个container实例。
+
+```jsx
+function Counter() {
+ return (
+
+ {counter => (
+
+ {counter.state.count}
+
+
+
+ )}
+
+ );
+}
+```
+
+`` 会自动构造container并监听其改变。
+
+##### ``
+
+最后一块儿,我们须要一个地方在内部存贮所有container实例。所以我们提供了 ``.
+
+```jsx
+render(
+
+
+
+);
+```
+
+我们可以用 `` 做一些有趣的事情,像是依赖注入:
+
+```jsx
+let counter = new CounterContainer();
+
+render(
+
+
+
+);
+```
+
+### Testing
+
+当我们在考虑怎样组织项目的state的时候,必须要考虑测试。
+
+我们希望确保状态容器保持"干净"。
+
+现在,因为我们的container都是简单的类,我们可以在测试时构建实例,轻松的写不同功能的断言。
+
+```js
+test('counter', async () => {
+ let counter = new CounterContainer();
+ assert(counter.state.count === 0);
+
+ await counter.increment();
+ assert(counter.state.count === 1);
+
+ await counter.decrement();
+ assert(counter.state.count === 0);
+});
+```
+
+如果我们想测试container和组件结合的功能,我们可以构建container实例并注入组件中测试。
+
+```js
+test('counter', () => {
+ let counter = new CounterContainer();
+ let tree = render(
+
+
+
+ );
+
+ await click(tree, '#increment');
+ assert(counter.state.count === 1);
+
+ await click(tree, '#decrement');
+ assert(counter.state.count === 0);
+});
+```
+
+依赖注入在许多方面很有用。比如,如果我们可以很方便的从状态container中提取出方法来,
+
+```js
+test('counter', () => {
+ let counter = new CounterContainer();
+ let inc = stub(counter, 'increment');
+ let dec = stub(counter, 'decrement');
+
+ let tree = render(
+
+
+
+ );
+
+ await click(tree, '#increment');
+ assert(inc.calls.length === 1);
+ assert(dec.calls.length === 0);
+});
+```
+
+我们不须要做任何清理,因为一切都是后置的。
+
+
+## FAQ
+
+#### 我要把哪些state放入Unstated?
+
+React社区聚焦于把所有状态放在同一个地方。你可以继续用Unstated这么做,我就不多说了。
+
+我想说的是分散化的方案。
+
+第一,尽量多的用组件state。上面的计数器其实根本不需要把state从组件中分离出来,不用Unstate也很好。
+
+第二,用一些库把一些多次用到的相关的state抽离。
+
+比如,表单让你很烦的话,你可能想用像[Final Form](https://github.com/final-form/react-final-form)这样的库.
+
+如果请求特别多,可以试一下 [Apollo](https://www.apollographql.com)这个库,或者类似的,一些像[Backbone models and collections](http://backbonejs.org)这样的不这么酷但很稳定的库。
+啥?你是不是太酷了,专用老的框架?
+
+第三,很多多组件共享的状态可以定位到组件树中的一个分支上。
+
+```jsx
+
+ One
+ Two
+ Three
+
+```
+这种情况,我建议用React内置的 `React.createContext()` API,并且要小心的设计基础组件的API;
+
+> **Note:** 如果你想在老版本的React中用新版React的context API,
+> [点这里](https://github.com/thejameskyle/create-react-context/)
+
+最后(当以上都干完时),如果你真是需要一些全局的状态在整个项目中共享,你就可以用Unstated了。
+
+我知道这些听起来可能很复杂,但这就是用正确的工具做正确的事的方式,真的不是整个宇宙都要用一套方法干活的。
+
+Unstated没有什么野心,你只要在需要它的时候再使用它就好了,所以它很小很漂亮。不要把它当成Redux杀手。不要想着基于它创建复杂的工具,不要总想着造轮子。玩儿玩儿它,看看你会不会喜欢它!
+
+#### 直接把自己的实例传入 ``
+
+如果你不关心依赖注入只想把你自己的container实例直接传入 ``,你可以:
+
+
+```jsx
+let counter = new CounterContainer();
+
+function Counter() {
+ return (
+
+ {counter => ...
}
+
+ );
+}
+```
+
+你要记住以下几点:
+1. 当你放弃依赖注入的方式时,就不能在测试中用`注入另一个实例了。
+2. 你的实例会存在于所有你传入实例的``中,如果你不是传入同一个引用的话,最后你的container会有多个实例。
+
+也请记住用 `` 注入实例也是挺好的,你应该在应该传入实例。在大部分情况下这样更好,因为这样能不但能获得依赖注入还获得其它所有良好特性。
+
+#### 怎样向container里传参?
+
+一个好的方式是,像React组件一样在container类里添加一个构造函数接受一个 `props` 。然后自己实例化它,再把实例传入 ``.
+
+```jsx
+class CounterContainer extends Container {
+ constructor(props = {}) {
+ super();
+ this.state = {
+ amount: props.initialAmount || 1,
+ count: 0
+ };
+ }
+
+ increment = () => {
+ this.setState({ count: this.state.count + this.state.amount });
+ };
+}
+
+let counter = new CounterContainer({
+ initialAmount: 5
+});
+
+render(
+
+
+
+);
+```
+
+## Related
+
+- [unstated-debug](https://github.com/sindresorhus/unstated-debug) - 方便的Debug你的Unstated container.
+