Skip to content

Commit

Permalink
use @redux/toolkit
Browse files Browse the repository at this point in the history
  • Loading branch information
mgrinko committed Jun 9, 2024
1 parent d04f8c4 commit 3098a35
Show file tree
Hide file tree
Showing 11 changed files with 87 additions and 117 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# React + Redux list of TODOs

> ❗ Read the lesson theory before solving this task
You are given an `app` folder with already implemented `store` and `hooks`.
Use them to implement [Dynamic list of TODOs](https://github.com/mate-academy/react_dynamic-list-of-todos#react-dynamic-list-of-todos)
using the Redux. It should look and work identically, so use the same markup.
Expand Down
44 changes: 34 additions & 10 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 2 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,14 @@
"dependencies": {
"@cypress/react18": "^2.0.0",
"@fortawesome/fontawesome-free": "^6.2.0",
"@reduxjs/toolkit": "^2.2.5",
"bulma": "^0.9.4",
"classnames": "^2.5.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-redux": "^8.1.3",
"react-router-dom": "^6.3.0",
"react-scripts": "^5.0.1",
"redux": "^4.2.1",
"redux-devtools-extension": "^2.13.9",
"redux-thunk": "^2.4.2"
"react-scripts": "^5.0.1"
},
"devDependencies": {
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
Expand Down
42 changes: 17 additions & 25 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,26 @@
/* eslint-disable max-len */
import React from 'react';
import 'bulma/css/bulma.css';
import '@fortawesome/fontawesome-free/css/all.css';
import { Loader, TodoFilter, TodoList, TodoModal } from './components';

import { TodoList } from './components/TodoList';
import { TodoFilter } from './components/TodoFilter';
import { TodoModal } from './components/TodoModal';
import { Loader } from './components/Loader';
export const App = () => (
<>
<div className="section">
<div className="container">
<div className="box">
<h1 className="title">Todos:</h1>

export const App: React.FC = () => {
return (
<>
<div className="section">
<div className="container">
<div className="box">
<h1 className="title">Todos:</h1>

<div className="block">
<TodoFilter />
</div>
<div className="block">
<TodoFilter />
</div>

<div className="block">
<Loader />
<TodoList />
</div>
<div className="block">
<Loader />
<TodoList />
</div>
</div>
</div>
</div>

<TodoModal />
</>
);
};
<TodoModal />
</>
);
5 changes: 0 additions & 5 deletions src/app/hooks.ts

This file was deleted.

22 changes: 5 additions & 17 deletions src/app/store.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,10 @@
import { createStore, applyMiddleware, combineReducers } from 'redux';
import { composeWithDevTools } from 'redux-devtools-extension';
import thunk from 'redux-thunk';
import { combineSlices, configureStore } from '@reduxjs/toolkit';

import currentTodoReducer from '../features/currentTodo';
import filterReducer from '../features/filter';
import todosReducer from '../features/todos';
const rootReducer = combineSlices();

const rootReducer = combineReducers({
currentTodo: currentTodoReducer,
filter: filterReducer,
todos: todosReducer,
export const store = configureStore({
reducer: rootReducer,
});

// The `store` is passed to the Provider in `/src/index.tsx`
export const store = createStore(
rootReducer,
composeWithDevTools(applyMiddleware(thunk)),
);

export type RootState = ReturnType<typeof store.getState>;
export type RootState = ReturnType<typeof rootReducer>;
export type AppDispatch = typeof store.dispatch;
4 changes: 4 additions & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export * from './Loader';
export * from './TodoList';
export * from './TodoFilter';
export * from './TodoModal';
37 changes: 6 additions & 31 deletions src/features/currentTodo.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,10 @@
import { createSlice } from '@reduxjs/toolkit';
import { Todo } from '../types/Todo';

// we use string literal as a type to avoid mistype in future
type RemoveTodoAction = { type: 'currentTodo/REMOVE' };
const initialState = null as Todo | null;

// payload is a typical name for an action data
type SetTodoAction = {
type: 'currentTodo/SET';
payload: Todo;
};

// Action creator return type protect us from a mistype
const removeTodo = (): RemoveTodoAction => ({ type: 'currentTodo/REMOVE' });

const setTodo = (todo: Todo): SetTodoAction => ({
type: 'currentTodo/SET',
payload: todo,
export const currentTodoSlice = createSlice({
name: 'currentTodo',
initialState,
reducers: {},
});

// These actions will be used in the application
export const actions = { setTodo, removeTodo };

type State = Todo | null;
type Action = SetTodoAction | RemoveTodoAction;

const currentTodoReducer = (state: State = null, action: Action): State => {
switch (action.type) {
// Implement all actions here

default:
return state;
}
};

export default currentTodoReducer;
18 changes: 9 additions & 9 deletions src/features/filter.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
export const actions = {
/* put action creators here */
};
import { createSlice } from '@reduxjs/toolkit';

const filterReducer = () => {
return {
query: '',
status: 'all',
};
const initialState = {
query: '',
status: 'all',
};

export default filterReducer;
export const filterSlice = createSlice({
name: 'filter',
initialState,
reducers: {},
});
13 changes: 6 additions & 7 deletions src/features/todos.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { createSlice } from '@reduxjs/toolkit';
import { Todo } from '../types/Todo';

export const actions = {};

const todosReducer = (): Todo[] => {
return [];
};

export default todosReducer;
export const todosSlice = createSlice({
name: 'todos',
initialState: [] as Todo[],
reducers: {},
});
11 changes: 2 additions & 9 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,10 @@ import { HashRouter as Router } from 'react-router-dom';
import { store } from './app/store';
import { App } from './App';

const container = document.getElementById('root') as HTMLElement;
const root = createRoot(container);

// Just a convenient component with all the wrappers for the `App`
// The Router component (if you use it) should be placed inside the Provider
const Root = () => (
createRoot(document.getElementById('root') as HTMLElement).render(
<Provider store={store}>
<Router>
<App />
</Router>
</Provider>
</Provider>,
);

root.render(<Root />);

0 comments on commit 3098a35

Please sign in to comment.