redux React,还原:显示所有帖子

ippsafx7  于 2022-11-24  发布在  React
关注(0)|答案(1)|浏览(112)

我是React、redux和web开发的初学者。我正在制作一个CRUD应用程序,使用JSON placeholder作为虚拟后端,reactredux用于显示帖子。
我想呈现出所有的职位形式JSON placeholder和简单地显示它

发布.js

import React, { useEffect, useState } from "react"
import { useDispatch, useSelector } from "react-redux"
import { useNavigate } from "react-router-dom"
import { getPostAll } from "../redux/features/PostSlice"

  return (
    <>
      <div className="row mt-4 d-flex align-items-center justify-content-center">
        <h2 className="row mt-4 d-flex align-items-center justify-content-center">
          Dashboard
        </h2>
      <div>
        <h2 className="row mt-4 d-flex align-items-center justify-content-center">
          All Posts
        </h2>
        {/* {console.log(getPostAll)} */}
        {console.log(dispatch(getPostAll()))}
        {dispatch(getPostAll).forEach((element) => {
          console.log(element)
        })}
      </div>
    </>
  )
}

export default Posts

后切片.js

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

export const getPost = createAsyncThunk("post/getPost", async ({ id }) => {
  return fetch(`https://jsonplaceholder.typicode.com/posts/${id}`).then((res) =>
    res.json()
  )
})

export const getPostAll = createAsyncThunk("posts/getPosts", async () => {
  return fetch(`https://jsonplaceholder.typicode.com/posts`)
    .then((res) => res.json())
    .then((json) => console.log(json, typeof json, json[0].id))
})

// export const getPostAll = fetch("https://jsonplaceholder.typicode.com/posts")
//   .then((response) => response.json())
//   .then((json) => console.log(json))

export const deletePost = createAsyncThunk(
  "post/deletePost",
  async ({ id }) => {
    return fetch(`https://jsonplaceholder.typicode.com/posts/${id}`, {
      method: "DELETE",
    }).then((res) => res.json())
  }
)
export const createPost = createAsyncThunk(
  "post/createPost",
  async ({ values }) => {
    return fetch(`https://jsonplaceholder.typicode.com/posts`, {
      method: "POST",
      headers: {
        Accept: "application/json",
        "Content-type": "application/json",
      },
      body: JSON.stringify({
        title: values.title,
        body: values.body,
      }),
    }).then((res) => res.json())
  }
)
export const updatePost = createAsyncThunk(
  "post/updatePost",
  async ({ id, title, body }) => {
    return fetch(`https://jsonplaceholder.typicode.com/posts/${id}`, {
      method: "PUT",
      headers: {
        Accept: "application/json",
        "Content-type": "application/json",
      },
      body: JSON.stringify({
        title,
        body,
      }),
    }).then((res) => res.json())
  }
)

const PostSlice = createSlice({
  name: "post",
  initialState: {
    post: [],
    loading: false,
    error: null,
    body: "",
    edit: false,
  },
  reducers: {
    setEdit: (state, action) => {
      state.edit = action.payload.edit
      state.body = action.payload.body
    },
  },
  extraReducers: {
    [getPost.pending]: (state, action) => {
      state.loading = true
    },
    [getPost.fulfilled]: (state, action) => {
      state.loading = false
      state.post = [action.payload]
    },
    [getPost.rejected]: (state, action) => {
      state.loading = false
      state.error = action.payload
    },
    [deletePost.pending]: (state, action) => {
      state.loading = true
    },
    [deletePost.fulfilled]: (state, action) => {
      state.loading = false
      state.post = [action.payload]
    },
    [deletePost.rejected]: (state, action) => {
      state.loading = false
      state.error = action.payload
    },
    [createPost.pending]: (state, action) => {
      state.loading = true
    },
    [createPost.fulfilled]: (state, action) => {
      state.loading = false
      state.post = [action.payload]
    },
    [createPost.rejected]: (state, action) => {
      state.loading = false
      state.error = action.payload
    },
    [updatePost.pending]: (state, action) => {
      state.loading = true
    },
    [updatePost.fulfilled]: (state, action) => {
      state.loading = false
      state.post = [action.payload]
    },
    [updatePost.rejected]: (state, action) => {
      state.loading = false
      state.error = action.payload
    },
  },
})
export const { setEdit } = PostSlice.actions
export default PostSlice.reducer

我想显示虚拟数据库中的所有帖子
我尝试过使用map functinality和forEach进行循环,但没有得到预期的结果。

zpqajqem

zpqajqem1#

您希望将 * 请求帖子 * 的任务与 * 访问帖子 * 的任务分开。
要请求帖子,你需要dispatch你的getPostAll操作。你只需要做一次,所以把它放在一个useEffect中。

const dispatch = useDispatch();

useEffect(() => {
   dispatch(getPostAll());
}, []);

您不需要在此返回任何内容。请记住,我们正在分离这些任务。
看起来你并没有真正响应你的reducer中的getPostAll thunk?这是一个你需要解决的问题。
使用一个或多个useSelector钩子来访问redux状态的当前值。这些值将在reducer响应由getPostAll启动的更改时自动更新。在第一次渲染时,您将没有数据,那么除了loading: true之外就没有数据了,最后要么有post,要么有error。您的组件需要为所有这些情况呈现正确的内容。

const Posts = () => {

  const dispatch = useDispatch();

  useEffect(() => {
     dispatch(getPostAll());
  }, []);

  const { post, loading, error } = useSelector(state => state.posts);

  // I find it easier to extract this part and `return` instead of using a bunch of `&&`
  const renderContent = () => {
    if (loading) {
      return <div>Loading...</div>;
    }
    if (error) {
      return <div>Error</div>;
    }
    if (post) {
      return (
        <div>
          {post.map(item => 
            <Post key={item.id} data={item}/>
          )}
        </div>
      );
    }
    return null;
  }

  return (
    <>
      <div className="row mt-4 d-flex align-items-center justify-content-center">
        <h2 className="row mt-4 d-flex align-items-center justify-content-center">
          Dashboard
        </h2>
      <div>
        <h2 className="row mt-4 d-flex align-items-center justify-content-center">
          All Posts
        </h2>
        {renderContent()}
      </div>
    </>
  )
}

相关问题