Skip to content

Commit d77fbe4

Browse files
committed
废除 state,现在可以直接访问this,数组也可直接通过方法更新页面
1 parent 0da6138 commit d77fbe4

File tree

5 files changed

+309
-121
lines changed

5 files changed

+309
-121
lines changed

README.md

Lines changed: 43 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,29 @@
22

33
---
44

5-
一个可以使搬砖更快乐的 Taro 扩展库
5+
一个可以使搬砖更快乐的 `Taro` 扩展库
66

77
目前提供了一组有状态的组件基类,只要使页面或组件继承对应的类,就可以享受非常舒适的 “双向数据绑定” 服务。
88

99

1010
# 扩展库自述
1111

1212
## 我是在什么情况下出生的?
13-
我的作者是一个重度Angular开发者,从Angularjs到Angular10,双向数据绑定已经在他的心中形成了一种习惯。他最近接手了一个小程序,一直对Taro比较感兴趣,正好又赶在了Taro3发布之际,所以他决定着手尝试一下。
13+
我的作者是一个重度 `Angular` 开发者,从 `Angular.js``Angular 10`,双向数据绑定已经在他的心中形成了一种习惯。他最近接手了一个小程序,一直对 `Taro` 比较感兴趣,正好又赶在了 `Taro3` 发布之际,所以他决定着手尝试一下。
1414

15-
可是从Angular跳到相对陌生的React,对他来说有些烫手,在尝试了Redux、MBox、和原生的setState后,他写出了第一版自动刷新工具:
15+
可是从 `Angular` 跳到相对陌生的 `React`,对他来说有些烫手,在尝试了 `Redux``MBox`、和原生的 `setState`,他写出了第一版自动刷新工具:
1616

17-
```
18-
【讨论贴】给React加上强制刷新,是种什么体验?
19-
https://github.com/NervJS/nerv/issues/163
20-
```
2117

22-
这个帖子反响并不是很好,他自己也知道帖子中的方法并不是一个理想的方式。所以他开始研究 vue 所使用的 Proxy。
18+
[【讨论贴】给React加上强制刷新,是种什么体验?](https://github.com/NervJS/nerv/issues/163)
19+
20+
21+
这个帖子反响并不是很好,他自己也知道帖子中的方法并不是一个理想的方式。所以他开始研究 `Vue` 所使用的 `Proxy`
2322

2423
经过几天实验,终于功夫不负有心人,我出生了。
2524

2625

27-
## 如何在Taro中拥有我
28-
由于作者的 npm 账户不是 vip账户,且公有包已经满5个了,所以无法推送至npm
26+
## 如何在 `Taro` 中拥有我
27+
由于作者的 `npm` 账户不是 `vip` 账户,且公有包已经满5个了,所以无法推送至 `npm`
2928

3029
不过值得欣慰的是 npm 可以通过 github 链接安装:
3130

@@ -36,94 +35,69 @@ npm install git+https://github.com/Eusen/taro-extras.git
3635

3736
## 我能干什么?
3837

39-
目前我最大的作用就是提供双向数据绑定:你可以在组件类中定义属性,并且利用 `this.state.xxx = ''` 更新值,我会感知到你的更新,并通知当前页面进行刷新。
38+
目前我最大的作用就是提供双向数据绑定:
39+
1. 你可以在组件类中随意定义属性,并且利用 `this.xxx = ''` 就可以更新页面上的值(我会感知到你的更新,并通知当前页面进行刷新)。
40+
2. 我可以绑定你指定的方法,将其this指向代理对象,这样你就可以不用写箭头函数,就可以访问正确的 this。
4041

4142
``` tsx
42-
import React from 'react';
43-
import {View, Button, Input, Text} from '@tarojs/components';
44-
// 导入 StatefulPage,组件请用 StatefulComponent
45-
import {StatefulPage} from "taro-extras";
46-
47-
import './index.scss'
48-
49-
export default class Index extends StatefulPage {
50-
// 直接定义属性
51-
list: any[] = [{value: '', sublist: [{value: ''}]}];
52-
53-
addItem = () => {
54-
// 添加新元素的话,还是需要这种方式,我暂时还没有拦截数组方法
55-
// 这里还是利用了 state ,但是不用担心,我将 state 的类型设置成了 this
56-
// 这样你就可以像访问 this 一样,访问 state
57-
this.state.list = [
58-
...this.state.list,
59-
{
60-
value: ''
61-
}
62-
];
43+
export default class IndexPage extends Stateful.Page {
44+
list = [{name: 'bob'}];
45+
46+
// 当自定义方法需要访问或改变this中的属性值时,请用 `@Stateful.bind()` 进行绑定
47+
@Stateful.bind()
48+
async load() {
49+
const resp = await Taro.request({...});
50+
// 赋值后,页面也会刷新
51+
this.list = resp.data.objects;
6352
}
6453

65-
input = item => {
66-
return (e) => {
67-
// 直接更新数组中的属性(不管几层),不需要 setState()
68-
item.value = e.detail.value;
54+
// 如果该方法没有访问 `this` 中的属性,则可以不用 `@Stateful.bind()` 绑定
55+
reverse() {
56+
return item => {
57+
item.name = item.name.split('').reverse().join('');
6958
}
7059
}
7160

72-
reset = item => {
73-
return () => {
74-
// 直接更新数组中的属性(不管几层),不需要 setState()
75-
item.value = '';
76-
};
77-
}
78-
7961
render() {
8062
return (
81-
<View className='index'>
63+
<View className='header-component'>
8264
{
83-
this.state.list.map((item, key) => {
65+
this.list.map((item, key) => {
8466
return (
8567
<View key={key}>
86-
<Text>Item</Text>
87-
<Input value={item.value} onInput={this.input(item)} />
88-
<Button onClick={this.reset(item)}>Reset</Button>
89-
{
90-
// 这里你可以看到是一个二维数组,
91-
// 即便是二维数组中的值,也可以直接赋值
92-
// 赋值后页面会自动刷新
93-
item.sublist && item.sublist.map((subitem, key2) => {
94-
return (
95-
<View key={key2}>
96-
<Text>Subitem</Text>
97-
<Input value={subitem.value} onInput={this.input(subitem)} />
98-
<Button onClick={this.reset(subitem)}>Reset</Button>
99-
</View>
100-
)
101-
})
102-
}
68+
<View>{item.name}</View>
69+
<Button onClick={this.reverse(item)}>Reverse</Button>
10370
</View>
10471
)
10572
})
10673
}
107-
<Button onClick={this.addItem}>Add Item</Button>
74+
// 直接写 this.load 就行,因为 bind 过,所以不用担心指向问题
75+
<Button onClick={this.load}>LoadMore</Button>
10876
</View>
10977
)
11078
}
11179
}
112-
11380
```
114-
上面这个例子虽然比较丑,但已经能够说明我的实力,我只有在你赋值的时候才会更新页面。
81+
上面这个例子已经能够说明我的作用,我只有在你赋值的时候才会更新页面,有很高的效率和性能
11582

11683

11784
## 在我帮助你时,你需要注意的地方
11885

119-
1. this.state 就是 Proxy,因为我的作者还没有想到如何替换页面中的this,如果想到了,也许就不需要 this.state 了~
86+
1. `1.1.0` 版本后,不再需要 state 属性,大家可以将其忽略,或作为一个普通属性看待;取而代之的是 `@Stateful.bind()` 绑定过的方法,可以直接访问 this 中的属性。
87+
88+
2. 组件需要继承 `Stateful.Component`,页面需要继承 `Stateful.Page`
12089

121-
2. 数组目前还是需要 [...arr, {}] 先解构再加新值。
90+
3.`implements` 以下 `Proxy Hooks` 以替代对应的 `React Hooks`
91+
- ProxyOnInit: `constructor` 没错,就是构造函数。不建议写构造,建议用 `onInit` 代替
92+
- ProxyAfterViewInit: `componentDidMount` => `afterViewInit`
93+
- ProxyOnChanges: `shouldComponentUpdate` => `onChanges`
94+
- ProxyOnCatch: `componentDidCatch` => `onCatch`
95+
- ProxyOnDestroy: `componentWillUnmount` => `onDestroy`
12296

12397

12498
## 谁创造了我?
12599

126-
[@Eusen](https://github.com/Eusen).
100+
[@Eusen](https://github.com/Eusen)
127101

128102

129103
## 参与创造我的人
@@ -133,8 +107,4 @@ export default class Index extends StatefulPage {
133107

134108
## 下一步计划
135109

136-
上面提到的两个问题就是下一步要解决的问题。
137-
138-
作者说他突然想的可以利用方法的bind来绑定proxy,这样就可以不用state挂载了。
139-
140-
数组的话也可以拦截方法,也许近期我会迎来一次升级~
110+
暂无计划,希望大家能积极尝试反馈,如果觉得好就给个小星星呗~

assets/logo.png

1.81 KB
Loading

0 commit comments

Comments
 (0)