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 应用可以说是绝配。
