Abstract illustration of Easy Peasy state management system with gears and a playful cat

Easy Peasy: Simplifying React State Management with a Vegetarian Twist

The Orange Cat
The Orange Cat

Introduction

In the world of React development, state management can often feel like a complex recipe with too many ingredients. Enter Easy Peasy, a state management library that serves up a delicious solution by abstracting Redux into a more palatable form. Easy Peasy focuses on developer experience, allowing you to whip up robust state management solutions quickly and easily, while still savoring the rich flavors of Redux’s architectural principles and ecosystem.

Features

Easy Peasy comes with a cornucopia of features that make state management a feast for developers:

  • Zero configuration: Get started immediately without the need for complex setup.
  • Minimal boilerplate: Say goodbye to repetitive code and hello to cleaner, more maintainable state logic.
  • React hooks-based API: Seamlessly integrate with modern React practices.
  • TypeScript support: Enjoy full type safety throughout your state management.
  • Computed properties: Derive state effortlessly for optimized performance.
  • Encapsulated side effects: Handle asynchronous operations with grace using built-in thunks.
  • Redux DevTools integration: Debug your application state with powerful developer tools.
  • Persistence: Easily save and rehydrate your application state.

Installation

Getting Easy Peasy onto your plate is as simple as running a single command:

npm install easy-peasy

For those who prefer Yarn:

yarn add easy-peasy

Basic Usage

Creating Your Store

Let’s start by creating a simple store to manage a list of todos:

import { createStore, action } from 'easy-peasy';

interface TodoModel {
  todos: string[];
  addTodo: (state: TodoModel, payload: string) => void;
}

const store = createStore<TodoModel>({
  todos: [],
  addTodo: action((state, payload) => {
    state.todos.push(payload);
  }),
});

In this example, we define a model with a todos array and an addTodo action. The action uses a mutation-style API, but don’t worry – Easy Peasy uses Immer under the hood to ensure immutability.

Wrapping Your Application

To make your store available throughout your React application, wrap your root component with the StoreProvider:

import { StoreProvider } from 'easy-peasy';
import { store } from './store';

function App() {
  return (
    <StoreProvider store={store}>
      <TodoList />
    </StoreProvider>
  );
}

Using State in Components

Access your store’s state using the useStoreState hook:

import { useStoreState } from 'easy-peasy';

function TodoList() {
  const todos = useStoreState((state) => state.todos);

  return (
    <ul>
      {todos.map((todo, index) => (
        <li key={index}>{todo}</li>
      ))}
    </ul>
  );
}

Dispatching Actions

To update your state, use the useStoreActions hook:

import { useStoreActions } from 'easy-peasy';

function AddTodoForm() {
  const addTodo = useStoreActions((actions) => actions.addTodo);
  const [newTodo, setNewTodo] = useState('');

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    addTodo(newTodo);
    setNewTodo('');
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        value={newTodo}
        onChange={(e) => setNewTodo(e.target.value)}
      />
      <button type="submit">Add Todo</button>
    </form>
  );
}

Advanced Usage

Computed Properties

Easy Peasy allows you to derive state using computed properties:

import { computed } from 'easy-peasy';

interface TodoModel {
  todos: { id: number; text: string; completed: boolean }[];
  completedTodos: number;
}

const store = createStore<TodoModel>({
  todos: [],
  completedTodos: computed((state) =>
    state.todos.filter(todo => todo.completed).length
  ),
});

Thunks for Asynchronous Actions

Handle asynchronous operations with thunks:

import { thunk } from 'easy-peasy';

interface TodoModel {
  todos: string[];
  fetchTodos: () => Promise<void>;
}

const store = createStore<TodoModel>({
  todos: [],
  fetchTodos: thunk(async (actions) => {
    const response = await fetch('/api/todos');
    const todos = await response.json();
    actions.setTodos(todos);
  }),
  setTodos: action((state, payload) => {
    state.todos = payload;
  }),
});

Persistence

Easily persist your state to local storage:

import { createStore, persist } from 'easy-peasy';

const store = createStore(
  persist(
    {
      todos: [],
      addTodo: action((state, payload) => {
        state.todos.push(payload);
      }),
    },
    {
      storage: 'localStorage',
    }
  )
);

Conclusion

Easy Peasy brings a refreshing simplicity to React state management without sacrificing the power and flexibility that Redux provides. By reducing boilerplate and offering an intuitive API, it allows developers to focus on building features rather than wrestling with complex state logic. Whether you’re working on a small project or a large-scale application, Easy Peasy provides a tasty solution that’s easy to pick up and hard to put down. Give it a try in your next React project, and experience the joy of state management made easy!

Comments