Skip to content

Instantly share code, notes, and snippets.

@integratorivan
Created November 21, 2025 08:45
Show Gist options
  • Select an option

  • Save integratorivan/6fc258372d83b604715a29c807b039c6 to your computer and use it in GitHub Desktop.

Select an option

Save integratorivan/6fc258372d83b604715a29c807b039c6 to your computer and use it in GitHub Desktop.
// reduxTodoStore.ts
import { legacy_createStore as createStore } from "redux";
export type Todo = {
id: number;
title: string;
done: boolean;
};
export type TodosState = {
items: Todo[];
};
const initialState: TodosState = {
items: [],
};
// Action types
const ADD_TODO = "ADD_TODO" as const;
const TOGGLE_TODO = "TOGGLE_TODO" as const;
const REMOVE_TODO = "REMOVE_TODO" as const;
// Action creators
export type AddTodoAction = {
type: typeof ADD_TODO;
payload: {
title: string;
};
};
export type ToggleTodoAction = {
type: typeof TOGGLE_TODO;
payload: {
id: number;
};
};
export type RemoveTodoAction = {
type: typeof REMOVE_TODO;
payload: {
id: number;
};
};
export type TodosAction = AddTodoAction | ToggleTodoAction | RemoveTodoAction;
export const addTodo = (title: string): AddTodoAction => ({
type: ADD_TODO,
payload: { title },
});
export const toggleTodo = (id: number): ToggleTodoAction => ({
type: TOGGLE_TODO,
payload: { id },
});
export const removeTodo = (id: number): RemoveTodoAction => ({
type: REMOVE_TODO,
payload: { id },
});
// Reducer
export const todosReducer = (
state: TodosState = initialState,
action: TodosAction
): TodosState => {
switch (action.type) {
case ADD_TODO: {
const newTodo: Todo = {
id: Date.now(),
title: action.payload.title,
done: false,
};
return {
...state,
items: [...state.items, newTodo],
};
}
case TOGGLE_TODO: {
return {
...state,
items: state.items.map((todo) =>
todo.id === action.payload.id
? { ...todo, done: !todo.done }
: todo
),
};
}
case REMOVE_TODO: {
return {
...state,
items: state.items.filter((todo) => todo.id !== action.payload.id),
};
}
default:
return state;
}
};
// Store
export const store = createStore(todosReducer);
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
@integratorivan

Copy link
Copy Markdown
Author
// zustandTodoStore.ts
import { create } from "zustand";

export type Todo = {
  id: number;
  title: string;
  done: boolean;
};

export type TodosState = {
  items: Todo[];
  addTodo: (title: string) => void;
  toggleTodo: (id: number) => void;
  removeTodo: (id: number) => void;
};

export const useTodosStore = create<TodosState>((set) => ({
  items: [],
  addTodo: (title: string) =>
    set((state) => {
      const newTodo: Todo = {
        id: Date.now(),
        title,
        done: false,
      };
      return {
        items: [...state.items, newTodo],
      };
    }),
  toggleTodo: (id: number) =>
    set((state) => ({
      items: state.items.map((todo) =>
        todo.id === id ? { ...todo, done: !todo.done } : todo
      ),
    })),
  removeTodo: (id: number) =>
    set((state) => ({
      items: state.items.filter((todo) => todo.id !== id),
    })),
}));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment