Redux Toolkit State issue when sending to child component

I am creating react redux application using redux toolkit and I’m passing some props to child component, it supposed to be one post because I’m using a map in parent component and passing one data to each component.

I’m trying to do Edit button and when clicking the “Edit button” trying to send ID to redux store but there is an error. If anyone know the answer please let me know.

Below is my redux slice:

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

import axios from "axios";
const initialState = {
  allPosts: [],
  loading: "idle",
  error: "",
  currentId: "",
};

export const fetchAlltAsync = createAsyncThunk(
  "allposts",
  async (_, thunkAPI) => {
    try {
      const response = await axios.get("http://localhost:5000/posts/");
      // The value we return becomes the `fulfilled` action payload
      return response.data;
    } catch (error) {
      throw thunkAPI.rejectWithValue({ error: error.message });
    }
  }
);

export const postsingleAsync = createAsyncThunk(
  "postsingleAsync",
  async (post, { dispatch }) => {
    const response = await axios.post("http://localhost:5000/posts/", post);

    return response.data;
  }
);
export const idsingleAsync = createAsyncThunk(
  "idsingleAsync",
  async (id, updatedpost) => {
    const response = await axios.patch(
      `http://localhost:5000/posts/${id}`,
      updatedpost
    );

    return response.data;
  }
);

export const postSlice = createSlice({
  name: "posts",
  initialState,
  // The `reducers` field lets us define reducers and generate associated actions
  reducers: {
    // Use the PayloadAction type to declare the contents of `action.payload`
    newsetcurrentId: (state, action) => {
      state.currentId = action.payload;
    },
  },
  // The `extraReducers` field lets the slice handle actions defined elsewhere,
  // including actions generated by createAsyncThunk or in other slices.
  extraReducers: (builder) => {
    builder.addCase(fetchAlltAsync.pending, (state) => {
      state.allPosts = [];
      state.loading = "Loading";
    });
    builder.addCase(fetchAlltAsync.fulfilled, (state, action) => {
      state.allPosts = action.payload;
      state.error += "Loaded";
    });
    builder.addCase(fetchAlltAsync.rejected, (state, action) => {
      state.allposts = "data not loaded";
      state.loading = "error";
      state.error = action.error.message;
    });
    builder.addCase(idsingleAsync.fulfilled, (state, action) => {
      state.currentId = action.payload;
    });
  },
});

export const { setcurrentId, newsetcurrentId } = postSlice.actions;

// The function below is called a selector and allows us to select a value from
// the state. Selectors can also be defined inline where they're used instead of
// in the slice file. For example: `useSelector((state: RootState) => state.counter.value)`
export const selectCount = (state) => state.counter.value;

// We can also write thunks by hand, which may contain both sync and async logic.
// Here's an example of conditionally dispatching actions based on current state.
export const incrementIfOdd = (amount) => (dispatch, getState) => {};

export default postSlice.reducer;

Below is my parent component:

import React, { useEffect, useState } from "react";
import Post from "./Post";
import { useSelector, useDispatch } from "react-redux";

const Posts = ({ SETCURRENTID, CURENTID }) => {
  // const dispatch = useDispatch();
  const posts = useSelector((state) => state.posts.allPosts);

  return (
    <div>
      {posts &&
        posts.map(({ _id, ...rest }) => (
          <Post key={_id} rest={rest} id={_id} />
        ))}
    </div>
  );
};

export default Posts;

This is my child component:

import React from "react";
import moment from "moment";
import { idsingleAsync, newsetcurrentId } from "../../features/postSlice";
import { useSelector, useDispatch } from "react-redux";

const Post = ({ rest, _id }) => {
  const dispatch = useDispatch();
  console.log(rest, "gff");
  //const { id } = this.rest._id;

  const handleClick = () => dispatch(newsetcurrentId());
  return (
    <div>
      <h1>{rest.title}</h1>
      <img
        style={{ maxWidth: "250px", border: "12px solid purple" }}
        alt="d"
        src={rest.selectedFile}
      />
      <h2>{moment(rest.createdAt).fromNow()}</h2>
      <button onClick={() => dispatch(newsetcurrentId(rest._id))}> edit</button>
      <h5>{rest.tags.map((tag) => `#${tag} `)}</h5>
      <h5 onClick={() => {}}>{rest.likeCount}</h5>
      <button onClick={() => {}}>Delete</button>
    </div>
  );
};

export default Post;

This is the redux error:

requestId(pin):undefined

Answer

TL;DR

Instead of rest._id , try passing the id prop to your newsetcurrentId dispatch:

const Post = ({ rest, id }) => { //Change _id to id
  const dispatch = useDispatch();

  const handleClick = () => dispatch(newsetcurrentId());
  return (
    <div>
      <h1>{rest.title}</h1>
      <img
        style={{ maxWidth: "250px", border: "12px solid purple" }}
        alt="d"
        src={rest.selectedFile}
      />
      <h2>{moment(rest.createdAt).fromNow()}</h2>
                              {/* pass id here */}
      <button onClick={() => dispatch(newsetcurrentId(id))}> edit</button>
      <h5>{rest.tags.map((tag) => `#${tag} `)}</h5>
      <h5 onClick={() => {}}>{rest.likeCount}</h5>
      <button onClick={() => {}}>Delete</button>
    </div>
  );
};

Explanation

When you are doing this destructuring: posts.map(({ _id, ...rest }) => ( your rest object will actually contain all the post properties apart from _id so you don’t actually have rest._id which you are trying to access on your Post child.

Additionally, you are passing id={_id} as a prop from the parent to the child, so you don’t actually have an _id prop on your Post component (change it to id).