How to use redux with React Hooks - Creating TodoList

Hello everyone in this article we are going to take a look at how we can use redux with React Hooks.

# What are React Hooks

React Hooks are functions that let us hook into React State and lifecycle features from functional components. Using redux with react hooks conceptually is same as we use it in class components but syntax wise they are bit different

To learn about this today we are going to create a simple ToDo List Application, here is a quick look


Use create-react-app to initialise a react app and install dependencies redux, react-redux

You will have basic react app folder structure by now. So let's create the redux store


import { createStore } from 'redux';

const INITIAL_STATE = {
  data: [
    'Get up early',
    'Have Breakfast',
    'Start coding'
  ],
};

function tasks(state = INITIAL_STATE, action) {
  switch (action.type) {
    case 'ADD_TASK':
      return { 
        ...state, 
        data: [...state.data, action.title] 
      };
    case 'REMOVE_TASK':
      return {
        ...state,
        data: [...action.tasks]
      }
    default:
      return state
  }
}

const store = createStore(tasks);

export default store;

Within Store I have created Initial state just with some dummy data and created reducers to handle two actions ADD_TASK and REMOVE_TASK

then created the store with createStore as usual

Now lets import the store in App component

import React from 'react';
import { Provider } from 'react-redux';
import store from './store';
import TodoList from './components/TodoList';
function App() {
  return (
    <Provider store={store}>
      <TodoList />
    </Provider>
  );
}
export default App;
In App component TodoList component is wrapped within Provider

From todolist component we will fetch all itms that are available in redux store and we will also add new tasks and push into store, we are going to need useSelector and useDispatch to perform the same, let's import them

import { useSelector, useDispatch } from 'react-redux';

To get data from store use

const tasks = useSelector(state => state.data);
For dispatching an action (eg. Add a task)

const addTaskAction = (title) => {
  return { type: 'ADD_TASK', title }
}
const TodoList = () => {
  ...
  ...
  const dispatch = useDispatch();
  const addTask = () => {
    dispatch(addTaskAction(task))
  }
  ...
  ...
}

So let's write TodoList component

import React,{useState} from 'react';
import { useSelector, useDispatch } from 'react-redux';
import Item from './Item';
import {Styles} from './style'

const addTaskAction = (title) => {
  return { type: 'ADD_TASK', title }
}
const TodoList = () => {
  const [task,setTask] = useState('')
  const tasks = useSelector(state => state.data);
  const dispatch = useDispatch();

  const addTask = () => {
    dispatch(addTaskAction(task))
    setTask('')
  }
  const taskOnChange = e => {
    setTask(e.target.value)
  }
  return (
    <div style={Styles.container}>
      <span style={Styles.header}>To-Do List</span>
      <input type="text" onChange={taskOnChange} value={task} />
      <button type="button" onClick={addTask}>
        Add Task
      </button>
      <div>
        { tasks.map((task,index) => <Item key={index} task={task} index={index} />) }
      </div>
    </div>
  );
}
export default TodoList

I have used another component Item to renders tasks one by one , Item component is also connected to the redux store as we need to remove tasks also

import React from 'react'
import { useSelector, useDispatch } from 'react-redux';
import {Styles} from './style'
const removeTaskAction = (tasks) => {
    return { type: 'REMOVE_TASK', tasks }
}

const Item = (props) =>{
    let tasks = useSelector(state => state.data);
    const dispatch = useDispatch();
    const removeTask = () =>{
        tasks.splice(props.index,1)
        dispatch(removeTaskAction(tasks))
    }
    return(
        <div style={Styles.item}>
            <span style={Styles.itemText}>{props.task}</span>
            <button onClick={removeTask}>remove</button>
        </div>
    )
}

export default Item

Github link for this codebase https://github.com/reactcodes/redux-with-react-hooks-todo-list

Thanks for your time , please share your feedback via comments and subscribe to my blog



Comments

Post a Comment

Popular posts from this blog

Best coding practice and structure for redux saga with react hooks | Separate watcher and worker saga | React clean code

Setting up Redux Devtools for React applications