Preact 使用 Storeon 进行状态管路
Storeon 是一个类似 Redux 的状态管理插件,根据官方的介绍为:“Redux” in 173 bytes 我个人其实一直不喜欢 Redux, 因为 Redux 的样板代码太多,需要写很多的 action, reducer,而且缺乏异步 action 触发的支持,需要借助其他的插件,例如 redux-thunk。而 Storeon 的灵感来源于 Redux, 但是很多概念和 api 都实现了简化,而且添加了异步 action 触发的支持,而且体积非常的小,支持目前主流的 js 框架,包括 React, Preact, Angular, Vue 和 Svelte。
这里介绍 Preact 结合 Storeon 的使用方法,Preact 也是一个非常小巧的类 React 库,相比于 React ,我更加喜欢 Preact 一点。
新建一个 Preact 项目:
npx preact-cli create default preactapp
添加 Storeon 包:
npm i storeon --save
接下来新建一个 store, 这里的概念跟 Redux 是一样的,也是全局单一状态对象,在这里首先新建一个 todos 的子状态:
文件: store/todos.js
export function todos(store) {
store.on('@init', () => ({todos: []}))
store.on('todos.save', (state, todo) => {
const {todos} = state;
return {
todos: [
...todos,
todo,
]
}
});
store.on('todos.delete', (state, index) => {
const {todos} = state;
todos.splice(index, 1);
return {
todos,
};
});
}
将其挂载到 store 里:
文件: store/index.js
import {createStoreon} from 'storeon';
import {todos} from './todos';
export const store = createStoreon(
[todos],
);
之后将 store 注入到组件中,修改 ./index.js 文件:
import './style';
import App from './components/app';
import { StoreContext } from 'storeon/preact';
import {store} from './store/index';
export default () => {
return(
<StoreContext.Provider value={store}>
<App />
</StoreContext.Provider>
);
};
这个 store 注入是组件只需要用到该状态组件到父组件即可,这里为了方便直接将其注入到 App 最顶层的组件。
接下来修改 ./routes/home/index.js 组件:
import { h } from 'preact';
import { useStoreon } from 'storeon/preact';
import style from './style.css';
import {useCallback, useState} from "preact/hooks";
const Home = () => {
const [todoTitle, setTodoTitle] = useState('');
const {dispatch, todos} = useStoreon('todos');
const todoAdd = () => {
dispatch('todos.save', {
title: todoTitle,
});
setTodoTitle('');
};
const todoDel = (index) => {
dispatch('todos.delete', index);
};
const todoTitleInput = useCallback((ev) => {
setTodoTitle(ev.target.value);
}, [todoTitle]);
return (
<div class={style.home}>
<h1>Todos</h1>
<div class="add-todo">
<input type="text" value={todoTitle} oninput={todoTitleInput} />
<button onclick={todoAdd}>Add Todo</button>
</div>
{todos.map((todo, index) => {
return (
<div key={index}>
<p>{todo.title}</p>
<button onclick={() => todoDel(index)}>del</button>
</div>
);
})}
</div>
);
};
export default Home;
一个最简单的 todo 应用就完成了,支持添加和删除:
这里使用了 Preact 的函数组件,基于类的组件的 Storeon 使用方法可以查看官方的文档,由于两者的体积都非常小巧,对于开发 H5 应用可以说是绝配。