TheDareback
TheDareback

Reputation: 407

How to rerender when Redux state is changed

Hi I have 2 components.

The first component provides a read (useSelector) from the Redux state object and renders its contents The second component ensures the insertion of new data into the same Redux state object

How to achieve that when a Redux state object changes with the help of the second component, the first component captures this change and renders the new content of the object again.

I tried to add in the component element:

useEffect(() => {
  ...some actions
}, [reduxStateObject]);

But it gives me too many requests.

/// EDIT add real example

  1. component

import React from "react";
import { useSelector } from "react-redux";

const ToDoList = () => {
  const { todos } = useSelector((state) => state.global);

  return (
    <div>
      <h1>Active</h1>
      {todos
        ?.filter((todo) => !todo.isCompleted)
        .sort((a, b) => (a.deadline < b.deadline ? 1 : -1))
        .map((todo, id) => {
          const date = new Date(todo.deadline).toLocaleString();

          return (
            <div key={id}>
              <p>{todo.text}</p>
              <p>{date}</p>
            </div>
          );
        })}
    </div>
  );
};

export default ToDoList;

  1. component

import React, { useEffect } from "react";
import { useDispatch } from "react-redux";
import { getToDoItems } from "../redux/globalSlice";

import ToDoList from "../components/ToDoList";

const ToDoWall = () => {
  const dispatch = useDispatch();

  useEffect(() => {
    dispatch(getToDoItems(1));
  }, [dispatch]);
  
    const submitForm = (e) => {
    dispatch(postToDoItem(e.data));
  };

  return (
    <>
      <ToDoList />
      <form onSubmit={submitForm}>
        <input type="text"></input>
        <input type="submit" value="" />
      </form>
    </>
  );
};

export default ToDoWall;

/// EDIT add Reducer

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

const initialState = {
  todos: null,
};

export const globalSlice = createSlice({
  name: "global",
  initialState,
  reducers: {
    setItems: (state, action) => {
      state.todos = action.payload;
    },
  },
});

export const { setItems } = globalSlice.actions;

export default globalSlice.reducer;

// Load todo items
export const getToDoItems = (id) => {
  return (dispatch) => {
    axios
      .get(`https://xxx.mockapi.io/api/list/${id}/todos`)
      .then((resp) => dispatch(setItems(resp.data)));
  };
};

// Post a list name
export const postNameList = (data) => {
  return (dispatch) => {
    axios.post("https://xxx.mockapi.io/api/list", {
      name: data,
    });
  };
};

// Post a todo item
export const postToDoItem = (id, data) => {
  return (dispatch) => {
    axios.post(
      `https://xxx.mockapi.io/api/list/${id}/todos`,
      {
        listId: id,
        title: data.title,
        text: data.text,
        deadline: +new Date(data.deadline),
        isCompleted: false,
      }
    );
  };
};

Upvotes: 1

Views: 6061

Answers (1)

I-vasilich-I
I-vasilich-I

Reputation: 258

As far as I understood, you don't need to do anything. When you dispatch action to change state in redux store, it'll change, and all components that use that state will get it, you don't need to worry about updating anything.

Upvotes: 1

Related Questions