为什么要有natur状态管理
我最开始使用的是redux,但是redux在开发时过于繁琐,开发效率较低,connect函数也较为麻烦。 想要性能优化,加上reselect,那就更复杂了,我只想做个业务与视图分离,让代码看起来清晰点。 之前我是做过redux的上层封装,虽然易用性改进了些,但是整体并不理想。 后来看了mobx,跟vuex很像,但是概念比较多,并且用惯了immutable,mobx用起来感觉有些不自在,有的时候会担心数据更新的方式过于随意,会引发一些潜在的性能问题。这些就让我在慢慢的去考虑我想要的状态管理器。
为啥要用natur
比较简单,基本上没什么要学习的概念。性能也不错(虽然没数据,但是你可以相信我)。
如果你不想用现在的状态管理器,你可以试试这个。
废话不多说,上个简单的计数器demo
import { createStore, inject } from "natur";
import React from "react";
const count = {
state: {
// 存放数据
number: 0
},
maps: {
// state的映射。比如,我需要知道state中的number是否是偶数,相当于vue或者mobx的计算属性
isEven: ["number", number => number % 2 === 0]
// 依赖声明可以使用函数方式
isEven2: [state => state.number, number => number % 2 === 0]
},
// 用来修改state。返回的数据会作为新的state(这部分由natur内部完成)
actions: {
// state number加1
inc: number => ({ number: number + 1 }),
// state number减1
dec: number => ({ number: number - 1 })
}
};
// 创建store这一步需要在渲染组件之前完成,因为在组件中,需要用到你创建的store
createStore({ count });
const App = ({ count }) => {
/*
// 组件中获取到的count如下
count: {
// state无变化
state: {
number: 0,
},
// maps会是计算后的结果
maps: {
isEven: true,
isEven2: true,
},
// actions,跟上面定义的一样用(其实内部已经包了一层)。
actions: {
inc: number => ({ number: number + 1 }),
dec: number => ({ number: number + 1 }),
}
}
*/
return (
<>
<button onClick={() => count.actions.dec(count.state.number)}>-</button>
<span>{count.state.number}</span>
<button onClick={() => count.actions.inc(count.state.number)}>+</button>
</>
);
};
// 向App组件中注入count模块
export default inject("count")(App);
没有provider或者context之类的东西。只要在渲染组件之前创建好store就行。
整体代码较为透明,应该比较容易理解。
以上就是基本用法,
复杂场景
就是加一些内置的中间件,使action用法更灵活。
比如: action支持异步、手动更新state,增量更新state,shallowEqual优化,支持redux的devtool这些。
// 这是natur内置常用的中间件, 推荐使用
import {
thunkMiddleware,
promiseMiddleware,
shallowEqualMiddleware,
fillObjectRestDataMiddleware,
filterUndefinedMiddleware
} from "natur/dist/middlewares";
import devtool from "./redux.devtool.middleware.js"; // 这个代码在官方文档里有
const count = {
state: {
name: ''
age: 0,
},
actions: {
changeName: newName => ({ name: newName }),
asyncChangeName: newName => Promise.resolve({ name: newName }), // 异步更新
thunkChangeName: newName => ({ getState, setState, getMaps }) => {
getState(); // 获取当前最新的state
getMaps(); // 获取当前最新的maps
setState({ name: newName }); // 设置state的name
}
}
}
// 创建store实例
const store = createStore({ count }, {}, undefined, [
// 这个是推荐的中间件配置,顺序也有要求,详细请查看中间件篇
thunkMiddleware, // action支持手动更新
promiseMiddleware, // 异步action
fillObjectRestDataMiddleware, // action支持增量更新state,上面action只更新了name,但是age数据不会丢失。
shallowEqualMiddleware, // shallowEqual优化
filterUndefinedMiddleware, // 过滤undefined
devtool //开发调试工具。
]);
其他功能
- 支持ts
- 支持js中直接使用natur
- 懒加载之类的
- ...
结语
希望natur对你有帮助,谢谢