[回到首页](../)
# 1.快速上手  
这一章我们来看看如何用 pastate 构建一个最简单的应用。

<!--ts-->
* [安装](#安装)
* [开始使用](#开始使用)
* [更新 state 值](#更新-state-值)
* [编辑器智能提示(intelliSense)](#编辑器智能提示intellisense)
<!--te-->

## 安装
Pastate 是一个 react 状态管理框架，需要配合 react 使用。我们先使用 [create-react-app](https://github.com/facebook/create-react-app) 工具创建一个基本的 react 项目，并在这个项目上演示如何使用 pastate：  
```
$ npm install -g create-react-app
$ create-react-app my-pastate-app
$ cd my-pastate-app
```  

然后，可以用 npm 直接安装 pastate：
```
$ npm install --save pastate
```
或使用 [yarn](https://yarnpkg.com/zh-Hans/) 安装：
```
$ yarn add pastate
```

## 开始使用  

Pastate 使用起来很简单，我们来创建一个 pastate 组件，显示简单的个人信息。  

创建 `src/MyPastateApp.jsx` 文件来编写我们的组件：

```javascript
import React, { Component } from 'react';
import { Pastore, makeOnlyContainer } from 'pastate';

const store = new Pastore({
    name: 'Peter',
    isBoy: true,
    age: 10
})

class AppView extends Component {
    render() {
        let state = store.state;
        return (
            <div>
                My name is {state.name}.<br/>
                I am a {state.isBoy ? "boy" : "girl"}.<br/>
                I am {state.age} years old.<br/>
            </div>
        )
    }
}

export default makeOnlyContainer(AppView, store)
```

完成，这就是一个入门的 pastate 组件，有以下两点区别于原生 react 项目：

1. 独立于组件的 **store**

```javascript
const store = new Pastore({
    name: 'Peter',
    isBoy: true,
    age: 10
})
```
Store 是一个**数据中心**，里面储存着 state 数据，并包含一套 state 管理引擎和视图更新引擎。

在初始化 store 时，需要向 Pastore 构造函数里传入一个初始化 state, 我们通常使用以下命名的方式书写, 以便复用这个初始化 state：
```javascript
const initState = {
    name: 'Peter',
    isBoy: true,
    age: 10
}
const store = new Pastore(initState)
```

2. 对组件和 store 进行连接  
对于只有唯一一个 store 的应用，我们使用 pastate 提供的 `makeOnlyContainer` 把 store 和组件(Component)连接成一个的**容器**, 这使得组件视图可以响应 store 中 state 的变化：  

![ Container 结构示意图](http://upload-images.jianshu.io/upload_images/1234637-2351f64be120cfb9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)  

接着，把该容器(Container)渲染在HTML中即可：  

`src/MyPastateApp.jsx`
```javascript
...
export default makeOnlyContainer(App, store)
```

`src/index.js`
```javascript
import ReactDOM from 'react-dom';
import container from './MyPastateApp';
ReactDOM.render(container, document.getElementById('root'));
```

注意，`makeOnlyContainer` 生成的是一个 React Element, 即 `<Xxx />`, 因此在 render 时不必再多加一层 <... />。

## 更新 state 值
接下来我们来尝试更新 state 的值：通过两个按钮来控制 state.age 值的增加和减少。
- 先在组件中添加两个操作函数 `increaseAge` 和 `decreaseAge`

```javascript
// src/MyPastateApp.jsx
...
const store = new Pastore(initState)
class AppView extends Component {

    increaseAge(){
        store.state.age += 1
    }
    
    decreaseAge(){
        store.state.age -= 1
    }

    render() {
        ...
    }
}
...
```
可以看到，使用 pastate 更新 state 非常简便：**直接对 state 中需要更新的节点进行赋值即可**，与 store 连接的视图会自动更新。

- 接下来在 JSX 中添加两个按钮来触发这两个操作函数：  
`src/MyPastateApp.jsx`
```javascript
...
    render() {
        let state = store.state;
        return (
            <div>
            
                My name is {state.name}.<br/>
                I am a {state.isBoy ? "boy" : "girl"}.<br/>
                I am {state.age} years old.<br/>
                
                <button onClick={this.decreaseAge}> decrease age </button> 
                <button onClick={this.increaseAge}> increase age </button> 
                
            </div>
        )
    }
...
```
Amazing！我们第一个简单的 pastate 应用大功告成：   

![第一个简单的 pastate 应用](http://upload-images.jianshu.io/upload_images/1234637-11e35381c42e9429.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)  

点击 `increaseAge` 和 `decreaseAge` 按钮， 可以看到年龄值的变化。
你可以再添加几个按钮来修改 state 中名字和性别，看看视图有没有如你所愿地更新。

Pastate 在 store 中实现了一个响应式和 immutable 特性结合的 state 管理引擎, 我们可以像修改普通变量一样操作 state, 同时 pastate 可以高效地根据 state 的改变对相关视图进行更新。

## 编辑器智能提示(intelliSense)
我们推荐使用 [Visual Studio Code](https://code.visualstudio.com/) 编辑器开发 react / pastate 应用，它拥有很好的变量类型智能提示功能和其他优秀特性，使得我们可以提高开发效率，并探测减少一些输入性错误。

Tips: vscode 默认关闭了通过 tab 键触发 emmet 的功能, 你可以通过修改设置开启： `"emmet.triggerExpansionOnTab": true ` 。

下面我们简单地使用 [jsDoc](http://usejsdoc.org/) 注释来使 state 具有类型提示效果:
`src/MyPastateApp.jsx`
```javascript
...
const initState = {
    name: 'Peter',
    isBoy: true,
    age: 10,
}
const store = new Pastore(initState)

/** @type {initState} */
const state = store.state; // 修改点, 把 state 提取成文件级的变量

class AppView extends Component {

    increaseAge(){
        state.age += 1 // 修改点，使用文件级的变量 state，下同
    }
    
    decreaseAge(){
        state.age -= 1 // 修改点
    }

    render() {
        // 修改点
        return (
            <div>
                My name is {state.name}.<br/> 
                I am a {state.isBoy ? "boy" : "girl"}.<br/>
                I am {state.age} years old.<br/>
                ... 
            </div>
        )
    }
}
...
    
```
- 我们把 store.state 提取为文件级的变量 state，这使得对 state 的使用和修改变得方便。
- 同时我们在 `const state` 之前加上类型注释 `/** @type {initState} */`, 使得编辑器知道 state 的格式，并获得如下的智能提示效果：  

![编辑器智能提示](http://upload-images.jianshu.io/upload_images/1234637-9d2c38cf9d9995f4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)  

智能提示的功能在 state 结构复杂的时候非常实用。  

你也可以使用 pastate 提供的 createStore 函数来创建 store, 并自动获取 state 类型定义，具体用法请看[API文档](https://github.com/BirdLeeSCUT/pastate/blob/master/dist/tools.d.ts)，我们现在先使用 new Pastore 的方式创建 store 。如果你使用 Typescript 进行开发，pastate 支持 Typescript 泛型的变量类型传递功能，无需使用 jsdoc 注释。

[下一章](./2.多组件应用.md)，我们看看如果构建一个包含多个组件的 pastate 应用。
