大家好,是我coral(反正你也不认识)。我今天来给大家介绍个我自己写的库meng。
一个声明式数据源+跨组件通讯库
介绍
目前react处理数据流的主流解决方案基本是redux了把。redux确实很经典,单向数据流,不可变和pure都很伟大。与此同时,redux也妖魔化了local state,其实本地状态并没有那么糟,甚至有的问题用本地状态做最合适不过了,比如一个侧边栏,你只需要把开关状态存在state里面就好。再加上redux的适合和配置都很繁琐,我决定用纯react写项目,然后为纯react写了个解决方案
在使用纯react遇到的最大的障碍目前看来是数据源和组件通讯。下面我来分享下用meng是怎么解决这两个问题的。
数据源
这是是官方例子:
componentDidMount(){
fetch(url).then(data => this.setState({data: data}))
}
这是redux:
import redux-1
import redux-2
import redux-3
import {action}
import Store
@connect(state => xxx)
class App {
componentDidMount() {
Store.dispatch(action)
}
}
这是meng的:
import {lift, resource}
@resource(() => fetch(url), todos)
@lift({todos: []})
class Todo {
}
我们看到react和redux都比较繁琐,数据源不透明,命令式。而meng带来的声明式数据源简化了这些操作,并且meng似乎在强调这样一种模型:
fetch(url) // producer
.todosomething() // wait time
.subscribe(react()) // cosumter
组件通讯
众所周知react通讯方式是回调,回调就算了,他还得一层层往下传。
redux是通过action和reducer把state放进store,然后组件再从里面拿
他们的代码我就不贴了,redux写起来没完。我的处理方式和redux差不多,但是提供了可以直接修改另一个组件的state的能力,代码看起来是这样的:
import Store, {lift} from 'meng'
class Login {
render() {
return (
<form>
<button onClick={this.login}>登陆</button>
<Modal />
</form>
)
}
login = () => {
fetch(url).then().catch(error => Store.Modal.setState({display: "block", message: error.message}))
}
}
@lift({display: "none", message: ""})
class Modal {}
组件通讯就是这么轻松简单。如果有必要你可以抽象自己的action层。
意外收获
假设这样一个问题,商品详情页(/detail/1)点击其他推荐商品,路由刷新了(/detail/2),但是页面没刷新,为什么?
因为你只在didmount里面获取数据了(不管是redux还是react),props变了你还需要重新获取,于是你的代码就变成这样了:
componentWillReceiveProps(nextProps) {
if(shallowEquals(this.props, nextProps)) {
dispatch(action)
}
}
componentDidMount(){
dispatch(action)
}
但是用meng的话只需要两行代码:
@resource(props => fetch(url), data)
@lift({data: {}})
class App {}
结束语
不需要额外的配置,不需要初始化,不需要import redux-xxx * N, 直接用原生react写项目吧
详情请看我是怎么写react的
召唤我的sponsor,@pinyin