vlambda博客
学习文章列表

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