随着Vue流行起来,使用响应式状态管理的方式愈发的流行,那么我们今天来试试在react中使用响应式状态管理方式
@lujs/use-reactive-state
@lujs/use-reactive-state是一个在react使用的响应式状态管理库,支持hooks
- 简单
- 帮助你划分ui和业务状态
- 完善的Typescript支持
这个是笔者两年前发布的一个react状态库,已经使用两年多了,欢迎使用
使用
首先安装@lujs/use-reactive-state
npm i @lujs/use-reactive-state
createReactiveState
使用createReactiveState方法来创建一个响应式对象
const vm = createReactiveState(object);
useReactiveState
使用useReactiveState在react中绑定响应式对象,就可以做到响应式更新了,具体看下方例子
import React from 'react';
import {
createReactiveState,
useReactiveState,
} from '@lujs/use-reactive-state';
class Vm {
name = 'use-react-state';
setName(name: string) {
this.name = name;
}
}
const vm = createReactiveState(new Vm());
const ComA = () => {
useReactiveState(vm);
return (
<div>
<p>name1:{vm.name}</p>
</div>
);
};
selector
支持选择器,比如下方的里只有在s.obj.age更新的时候才会触发组件渲染
const state = createReactiveState({
name: 'lujs',
obj: {
age: 18,
},
});
// ComA will render when state.obj.age change
const ComA = () => {
useReactiveState(state, s => s.obj.age);
return (
<div>
<p>name1:{state.obj.age}</p>
</div>
);
};
debug
在浏览器中使用react dev tool可以看到debug的状态
TodoList
下面演示一个简单的Todolist
import {
createReactiveState,
useReactiveState,
} from '@lujs/use-reactive-state';
import React, { useRef, useEffect } from 'react';
class Todo {
content = '';
id = '';
status: 'done' | 'default' | 'delete' = 'default';
constructor(content: string) {
this.content = content;
this.id = Math.random().toString();
}
finish() {
if (this.status === 'default') {
this.status = 'done';
} else if (this.status === 'done') {
this.status = 'delete';
}
}
setContent(s: string) {
this.content = s;
}
}
class TodoList {
list: Todo[] = [];
addTodo(content: string) {
const todo = new Todo(content);
this.list.push(todo);
}
init() {
this.addTodo('todo 1');
}
finish(id: string) {
this.list.forEach(v => {
if (v.id === id) {
v.finish();
}
});
}
defaultList() {
return this.list.filter(v => v.status === 'default');
}
doneList() {
return this.list.filter(v => v.status === 'done');
}
deleteList() {
return this.list.filter(v => v.status === 'delete');
}
}
const viewModel = createReactiveState(new TodoList());
const Index = () => {
const refInput = useRef<HTMLInputElement>(null);
useReactiveState(viewModel);
const defaultList = viewModel.defaultList();
const doneList = viewModel.doneList();
const deleteList = viewModel.deleteList();
useEffect(() => {
viewModel.init();
}, []);
return (
<div>
<div style={{ paddingLeft: '40px', marginBottom: '20px' }}>
<input type="text" ref={refInput} />
<button
style={{ marginLeft: '20px' }}
type="button"
onClick={() => {
if (refInput.current) {
const content = refInput.current.value;
if (content) {
viewModel.addTodo(content);
}
}
}}
>
add todo
</button>
</div>
<ul>
default List:
{defaultList.map(v => {
return (
<li key={v.id}>
{v.content} status: {v.status}
<button
style={{ marginLeft: '20px' }}
type="button"
onClick={() => {
viewModel.finish(v.id);
}}
>
finish
</button>
</li>
);
})}
</ul>
<ul>
done List:
{doneList.map(v => {
return (
<li key={v.id}>
{v.content} status: {v.status}
<button
style={{ marginLeft: '20px' }}
type="button"
onClick={() => {
viewModel.finish(v.id);
}}
>
finish
</button>
</li>
);
})}
</ul>
<ul>
delete List:
{deleteList.map(v => {
return (
<li key={v.id}>
<del>
{v.content} status: {v.status}
</del>
</li>
);
})}
</ul>
</div>
);
};
export default Index;
在线例子可以点击这里查看
贴上源码 👉🏻 源码
期待宝子们的star⭐️,你的支持就是我最大的动力
其他文章
什么?在React中也可以使用vue响应式状态管理
clean-js | 自从写了这个辅助库,我已经很久没有加过班了…
clean-js | 在hooks的时代下,使用class管理你的状态
clean-js | 手把手教你写一个羊了个羊麻将版
写给前端的数据库入门 | 序
写给前端的数据库入门 | docker & 数据库
有没有一种可能,你从来都没有真正理解async
三分钟实现前端写JAVA这件事——装环境
三分钟实现前端写JAVA这件事——VS code