Home  >  Article  >  Web Front-end  >  A brief discussion on the state management method of React+Storeon

A brief discussion on the state management method of React+Storeon

青灯夜游
青灯夜游forward
2021-04-15 12:48:262532browse

This article will introduce you to the method of using event-driven state management in React. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to everyone.

A brief discussion on the state management method of React+Storeon

Since Hooks were introduced into React, the Context API and Hook library have been used together in application state management. But combining the Context API with Hooks (on which many Hooks-based state management libraries are built) may not be efficient for large-scale applications.

Since a custom Hook must be created to enable access to the state and its methods before it can be used in the component, it is cumbersome in actual development. This defeats the real purpose of Hooks: simplicity. But for smaller applications, Redux may seem too heavy.

Today we will discuss an alternative to the Context API: Storeon. Storeon is a tiny, event-driven state management library for React that works similarly to Redux. Use Redux DevTools to view and visualize state operations. Storeon internally uses Context API to manage state and adopts an event-driven approach for state operations.

[Related tutorial recommendations: React video tutorial]

Store

store is the data stored in the application state collection. It is created through the createStoreon() function imported from the Storeon library. The

createStoreon() function accepts a list of modules, where each module is a function that accepts a store parameter and binds its event listener. Here is an example of a store:

import { createStoreon } from 'storeon/react'
// todos module
const todos = store => {
  store.on(event, callback)
}

export default const store = createStoreon([todos])

Modularity

The stores in Storeon are modular, that is, they are defined independently and are not Bind to a Hook or component. Each state and its operation methods are defined in functions called modules. These modules are passed into the createStoreon() function, which is then registered as a global store.

store has three methods:

  • store.get() – used to retrieve the current data in the state.

  • store.on(event, callback) – Used to register an event listener to the specified event name.

  • store.dispatch(event, data) – Used to emit events and pass in optional data based on defined event requirements.

Events

Storeon is an event-based state management library, and state changes are emitted by events defined in the state module. There are three built-in events in Storeon, they start with @. Other events are defined without the @ prefix. The three built-in events are:

  • @init – This event is fired when the app loads. It is used to set the initial state of the app and execute anything in the callbacks passed to it.

  • @dispatch – This event fires on every new action. This is useful for debugging.

  • @changed – This event is fired when the application state changes.

Note: store.on(event, callback) is used to add event listeners in our module.

Demo program

To demonstrate how to perform application state operations in Storeon, we will build a simple notes program. Another package from Storeon will also be used to save state data in localStorage.

Assume you have basic knowledge of JavaScript and React. You can find the code used in this article at https://github.com/Youngestde....

Setup

Before we dive in, let’s outline the project structure and installation of dependencies required by the Notes program. Start by creating the project folder.

mkdir storeon-app && cd storeon-app
mkdir {src,public,src/Components}
touch public/{index.html, style.css} && touch src/{index,store,Components/Notes}.js

Next, initialize the directory and install the required dependencies.

npm init -y
npm i react react-dom react-scripts storeon @storeon/localstorage uuidv4

The next step is to write the parent component in the index.js file.

index.js

This file is responsible for rendering our note component. First import the required packages.

import React from 'react'
import { render } from 'react-dom';

function App() {
  return (
    <>
      Hello!
    </>
  );
}
const root = document.getElementById(&#39;root&#39;);
render(<App />, root);

Next build the store by writing code for initialization and manipulation of state in store.js.

store.js

This file is responsible for handling the state and subsequent state management operations in the application. We have to create a module to store state and support events to handle operational changes.

First, import the createStoreon method and unique random ID generator UUID from Storeon.

createStoreon method is responsible for registering our state to the global store.

import { createStoreon } from &#39;storeon&#39;;
import { v4 as uuidv4 } from &#39;uuid&#39;
import { persistState } from &#39;@storeon/localstorage&#39;;

let note = store => {}

We store the status in the array variable notes, which contains notes in the following format:

{
  id: &#39;note id&#39;,
  item: &#39;note item&#39;
},

接下来,我们将用两个注释(在首次启动程序时会显示)来初始化状态,从而首先填充注释模块。然后,定义状态事件。

let note = store => {
  store.on(&#39;@init&#39;, () => ({
    notes: [
      { id: uuidv4(), item: &#39;Storeon is a React state management library and unlike other state management libraries that use Context, it utilizes an event-driven approach like Redux.&#39; },
      { id: uuidv4(), item: &#39;This is a really short note. I have begun to study the basic concepts of technical writing and I&#39;\&#39;m optimistic about becoming one of the best technical writers.&#39; },
    ]
  });
  store.on(&#39;addNote&#39;, ({ notes }, note) => {
    return {
      notes: [...notes, { id: uuidv4(), item: note }],
    }
  });
  store.on(&#39;deleteNote&#39;, ({ notes }, id) => ({
    notes: notes.filter(note => note.id !== id),
  });
}

在上面的代码中,我们定义了状态,并用两个简短的注释填充了状态,并定义了两个事件和一个从  dispatch(event, data)  函数发出事件后将会执行的回调函数。

addNote 事件中,我们返回添加了新 note 的更新后的状态对象,在 deleteNote 事件中把 ID 传递给调度方法的 note 过滤掉。

最后,把模块分配给可导出变量 store ,将其注册为全局 store,以便稍后将其导入到上下文 provider 中,并将状态存储在 localStorage 中。

const store = createStoreon([
  notes,
  // Store state in localStorage
  persistState([&#39;notes&#39;]),
]);
export default store;

接下来,在 Notes.js 中编写 Notes 应用组件。

Notes.js

此文件包含 Notes 程序的组件。我们将从导入依赖项开始。

import React from &#39;react&#39;;
import { useStoreon } from &#39;storeon/react&#39;;

接下来,编写组件。

const Notes = () => {
  const { dispatch, notes } = useStoreon(&#39;notes&#39;);
  const [ value, setValue ] = React.useState(&#39;&#39;); 
}

在上面的代码的第二行中,useStoreon()  hook 的返回值设置为可破坏的对象。 useStoreon() hook 使用模块名称作为其参数,并返回状态和调度方法以发出事件。

接下来定义在组件中发出状态定义事件的方法 。

const Notes = () => {
...
  const deleteNote = id => {
    dispatch(&#39;deleteNote&#39;, id)
  };
  const submit = () => {
    dispatch(&#39;addNote&#39;, value);
    setValue(&#39;&#39;);
  };
  const handleInput = e => {
    setValue(e.target.value);
  };
}

Let’s review the three methods we defined the above:
让我们回顾一下上面定义的三种方法:

  • deleteNote(id) – 此方法在触发时调度 deleteNote 事件。

  • submit() – 该方法通过传递输入状态的值来调度 addNote 事件,该状态在 Notes 组件中本地定义。

  • handleInput() – 此方法将本地状态的值设置为用户输入。

Next, we’ll build the main interface of our app and export it.
接下来,我们将构建应用程序的主界面并将其导出。

const Notes = () => {
  ...
  return (
    <section>
      <header>Quick Notes</header>

      <div className=&#39;addNote&#39;>
        <textarea onChange={handleInput} value={value} />
        <button onClick={() => submit()}> Add A Note </button>
      </div>

      <ul>
        {notes.map(note => (
          <li key={note.id}>
            <div className=&#39;todo&#39;>
              <p>{note.item}</p>
              <button onClick={() => deleteNote(note.id)}>Delete note</button>
            </div>
          </li>
        ))}
      </ul>
    </section>
  );
}

这样就构成了我们的 Notes 组件。接下来为我们的应用和 index.html 文件编写样式表。

index.html

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" href="style.css">
    <title>Storeon Todo App</title>
</head>

<body>
    <div id="root"></div>
</body>

</html>

接下来,填充我们的 style.css 文件。

style.css

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

section {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  width: 300px;
  margin: auto;
}

header {
  text-align: center;
  font-size: 24px;
  line-height: 40px;
}

ul {
  display: block;
}

.todo {
  display: block;
  margin: 12px 0;
  width: 300px;
  padding: 16px;
  box-shadow: 0 8px 12px 0 rgba(0, 0, 0, 0.3);
  transition: 0.2s;
  word-break: break-word;
}

li {
  list-style-type: none;
  display: block;
}

textarea {
  border: 1px double;
  box-shadow: 1px 1px 1px #999;
  height: 100px;
  margin: 12px 0;
  width: 100%;
  padding: 5px 10px;
}

button {
  margin: 8px 0;
  border-radius: 5px;
  padding: 10px 25px;
}

.box:hover {
  box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.2);
}

运行

现在我们已经成功编写了组件和样式表,但是还没有更新 index.js 中的父组件来渲染 Notes 组件。接下来让我们渲染 Notes 组件。

index.js

要访问我们的全局 store,必须导入 store 和 Storeon store 上下文组件。我们还将导入 notes 组件来进行渲染。

用以下代码替换组件的内容:

import React from &#39;react&#39;;
import { render } from &#39;react-dom&#39;;
import { StoreContext } from &#39;storeon/react&#39;;
import Notes from &#39;./Components/Notes&#39;;
import store from &#39;../src/store&#39;;

function App() {
  return (
    <>
      <StoreContext.Provider value={store}>
        <Notes />
      </StoreContext.Provider>
    </>
  );
}

const root = document.getElementById(&#39;root&#39;);
render(<App />, root);

在第 8-10 行,调用 store 上下文提供程序组件,并将 notes 组件作为使用者传递。store 上下文提供程序组件将全局 store 作为其上下文值。

接下来把 package.json 文件中的脚本部分编辑为以下内容:

"scripts": {
  "start": "react-scripts start",
}

然后运行我们的程序:

npm run start

让我们继续添加和删除注释:

A brief discussion on the state management method of React+Storeon

Storeon devtools

Storeon 与 Redux 有着相似的属性,可以在 Redux DevTools 中可视化和监视状态的更改。为了可视化 Storeon 程序中的状态,我们将导入 devtools 包,并将其作为参数添加到我们 store.js 文件的 createStoreon() 方法中。

...
import { storeonDevtools } from &#39;storeon/devtools&#39;;
...
const store = createStoreon([
  ...,
  process.env.NODE_ENV !== &#39;production&#39; && storeonDevtools,
]);

这是用 Redux DevTools 可视化状态变化的演示:

A brief discussion on the state management method of React+Storeon

结论

Storeon 是一个非常有用的状态管理库,它用事件驱动和 Redux 改编的模块化样式来管理状态。你可以在https://github.com/Youngestdev/storeon-app上找到本文中的代码。

原文地址:https://blog.logrocket.com/event-driven-state-management-in-react-using-storeon/

作者:Abdulazeez Abdulazeez Adeshina

更多编程相关知识,请访问:编程视频!!

The above is the detailed content of A brief discussion on the state management method of React+Storeon. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:segmentfault.com. If there is any infringement, please contact admin@php.cn delete