Nima Zarei
Nima Zarei

Reputation: 1228

Redux action fires twice

I have this redux todo app that updates the state of the remaining tasks based on the number of incomplete tasks.

The app is working without any errors or problems but when I add a task, toggle completion, and remove a task, the action type of remainingTasks/updateRemainingTasks fires twice:

enter image description here

enter image description here

Interestingly, that action only fires once when removing a task that has been completed:

enter image description here

These are the code for that slice and its corresponding component:

SLICE

import { createSlice } from "@reduxjs/toolkit";

const remainingTasksSlice = createSlice({
  name: "remainingTasks",
  initialState: 0,
  reducers: {
    updateRemainingTasks: (state, action) => {
      return action.payload;
    },
  },
});

// Selectors
export const selectRemainingTasksSlice = (state) => state.remainingTasksReducer;

// Actions
export const { updateRemainingTasks } = remainingTasksSlice.actions;

// Reducers
export default remainingTasksSlice.reducer;

COMPONENT

import { useSelector, useDispatch } from "react-redux";
import {
  selectRemainingTasksSlice,
  updateRemainingTasks,
} from "./remainingTasksSlice";
import { selectTaskSlice } from "../task/taskSlice";

const RemainingTasks = () => {
  const dispatch = useDispatch();
  const remainingTasksSlice = useSelector(selectRemainingTasksSlice);
  const taskSlice = useSelector(selectTaskSlice);

  // Number of Incomplete Tasks
  const incompleteTasks = taskSlice.filter((task) => !task.completed).length;

  // Update the State of the Remaining Tasks
  dispatch(updateRemainingTasks(incompleteTasks));

  return (
    <div>
      <h1 className="header">
        {remainingTasksSlice > 1
          ? `${remainingTasksSlice} Tasks Left`
          : `${remainingTasksSlice} Task Left`}
      </h1>
    </div>
  );
};

export default RemainingTasks;

I was wondering if this is a normal thing or my code isn't well optimized.

Upvotes: 1

Views: 2154

Answers (1)

Max
Max

Reputation: 1048

I think you have to call dispatch into a useEffect hook:

....
useEffect(()=>{
    // Number of Incomplete Tasks
    const incompleteTasks = taskSlice.filter((task) => !task.completed).length;
    // Update the State of the Remaining Tasks
    dispatch(updateRemainingTasks(incompleteTasks));
}, [taskSlice]);
....

otherwise you call dispatch every time you render the Component.

Upvotes: 2

Related Questions