我正在尝试删除帖子,但好像我必须每次刷新页面。当我查看Chrome中的React devtools时,商店也在刷新后更新。我需要了解其背后的原因。
因此,我在UserPosts
之类的路线上有一个www.abc.com/profile/jimmy/posts
组件。此页面以卡片形式包含用户的帖子。这些也具有删除按钮。
UserPosts.js
import React, { Component } from "react"
import { getUserPosts, getCurrentUser } from "../actions/userActions"
import { connect } from "react-redux"
import Cards from "./Cards"
class UserPosts extends Component {
componentDidMount() {
const authToken = localStorage.getItem("authToken")
if (authToken) {
this.props.dispatch(getCurrentUser(authToken))
if (this.props && this.props.userId) {
this.props.dispatch(getUserPosts(this.props.userId))
} else {
return null
}
}
}
render() {
const { isFetchingUserPosts, userPosts } = this.props
console.log(userPosts)
return isFetchingUserPosts ? (
<p>Fetching....</p>
) : (
<div>
{userPosts &&
userPosts.map(post => {
return <Cards key={post._id} post={post} />
})}
</div>
)
}
}
const mapStateToPros = state => {
return {
isFetchingUserPosts: state.userPosts.isFetchingUserPosts,
userPosts: state.userPosts.userPosts,
userId: state.auth.user._id
}
}
export default connect(mapStateToPros)(UserPosts)
Cards.js
import React, { Component } from "react"
import { connect } from "react-redux"
import { deletePost } from "../actions/userActions"
class Cards extends Component {
handleDelete = (_id) => {
this.props.dispatch(deletePost(_id))
}
render() {
const { _id, title, description } = this.props.post
return (
<div className="card">
<div className="card-content">
<div className="media">
<div className="media-left">
<figure className="image is-48x48">
<img
src="https://bulma.io/images/placeholders/96x96.png"
alt="Placeholder image"
/>
</figure>
</div>
<div className="media-content" style={{border: "1px grey"}}>
<p className="title is-5">{title}</p>
<p className="content">{description}</p>
<button className="button is-success">Edit</button>
<button onClick={() => {this.handleDelete(_id)}} className="button is-success">Delete</button>
</div>
</div>
</div>
</div>
)
}
}
const mapStateToProps = () => {
return {
nothing: "nothing"
}
}
export default connect(mapStateToProps)(Cards)
删除发布操作
export const deletePost = (id) => {
return async (dispatch) => {
dispatch({ type: "DELETING_POST_START" })
try {
const deletedPost = await axios.delete(`http://localhost:3000/api/v1/posts/${id}/delete`)
dispatch({
type: "DELETING_POST_SUCCESS",
data: deletedPost
})
} catch(error) {
dispatch({
type: "DELETING_POST_FAILURE",
data: { error: "Something went wrong" }
})
}
}
}
userPosts reducer
const initialState = {
isFetchingUserPosts: null,
isFetchedUserPosts: null,
userPosts: [],
fetchingUserPostsError: null
}
const userPosts = (state = initialState, action) => {
switch (action.type) {
case "FETCHING_USER_POSTS_START":
return {
...state,
isFetchingUserPosts: true,
fetchingUserPostsError: null
}
case "FETCHING_USER_POSTS_SUCCESS":
return {
...state,
isFetchingUserPosts: false,
isFetchedUserPosts: true,
userPosts: action.data,
fetchingUserPostsError: null
}
case "FETCHING_USER_POSTS_ERROR":
return {
...state,
isFetchingUserPosts: false,
isFetchedUserPosts: false,
fetchingUserPostsError: action.data.error
}
default:
return state
}
}
export default userPosts
后减速器
const initialState = {
isAddingPost: false,
postError: null,
post: {},
isFetchingPosts: null,
isFetchedPosts: null,
fetchingPostsError: null,
isDeletingPost: false,
isDeletedPost: false,
deletingError: null,
postList: []
}
const post = (state = initialState, action) => {
switch (action.type) {
case "ADD_POST_STARTS":
return { ...state, isAddingPost: true, postError: null }
case "ADD_POST_SUCCESS":
return {
...state,
isAddingPost: false,
postError: null,
post: action.data
}
case "ADD_POST_ERROR":
return {
...state,
isAddingPost: false,
postError: action.data.error,
post: {}
}
case "FETCHING_POSTS_START":
return {
...state,
isFetchingPosts: true,
isFetchedPosts: false,
fetchingPostsError: null
}
case "FETCHING_POSTS_SUCCESS":
return {
...state,
isFetchingPosts: false,
isFetchedPosts: true,
fetchingPostsError: null,
postList: action.data.posts
}
case "FETCHING_POSTS_ERROR":
return {
...state,
isFetchingPosts: false,
isFetchedPosts: false,
fetchingPostsError: action.data.error
}
case "DELETING_POST_START":
return {
...state,
isDeletingPost: true,
deletingError: null
}
case "DELETING_POST_SUCCESS":
const filteredPostList = state.postList.filter(
post => post._id !== action.data._id
)
return {
...state,
isDeletingPost: false,
isDeletedPost: true,
postList: filteredPostList,
deletingError: null
}
case "DELETING_POST_ERROR":
return {
...state,
isDeletingPost: false,
deletingError: action.data.error
}
default:
return state
}
}
export default post
我只需要知道如何解决此问题以及为什么它没有按预期发生。谢谢。
编辑:我也有一个deletePost
控制器。是造成问题的原因吗?
router.delete("/:id/delete", postsController.deletePost)
deletePost: async (req, res, next) => {
try {
const post = await Post.findByIdAndDelete(req.params.id)
if (!post) {
return res.status(200).json({ error: "No post found"})
}
return res.status(200).json({ post })
} catch(error) {
return res.json({ error })
}
}
答案 0 :(得分:0)
请确保您在删除项目时API返回ID,如果确实如此,请确保它在_id
中返回。
这里有一些重构,所以看起来更易读:
UserPosts.js
import React, { Component } from "react";
import { getUserPosts, getCurrentUser } from "../actions/userActions";
import { connect } from "react-redux";
import Cards from "./Cards";
class UserPosts extends Component {
componentDidMount() {
const authToken = localStorage.getItem("authToken");
const { getCurrentUser, getUserPosts, userId } = this.props;
if (authToken) {
getCurrentUser(authToken);
userId ? getUserPosts(userId) : null;
}
}
render() {
const { isFetchingUserPosts, userPosts } = this.props;
return isFetchingUserPosts ? (
<p>Fetching....</p>
) : (
<div>
{userPosts &&
userPosts.map((post) => {
return <Cards key={post._id} post={post} />;
})}
</div>
);
}
}
const mapStateToPros = (state) => {
return {
isFetchingUserPosts: state.userPosts.isFetchingUserPosts,
userPosts: state.userPosts.userPosts,
userId: state.auth.user._id,
};
};
const mapDispatchToProps = (dispatch) => {
return {
getCurrentUser: (authToken) => {
dispatch(getCurrentUser(authToken));
},
getUserPosts: (userId) => {
dispatch(getUserPosts(userId));
},
};
};
export default connect(mapStateToPros)(UserPosts);
Cards.js
class Cards extends Component {
handleDelete = (id) => {
this.props.deletePost(id);
};
render() {
const { _id, title, description } = this.props.post;
return (
<div className="card">
<div className="card-content">
<div className="media">
<div className="media-left">
<figure className="image is-48x48">
<img
src="https://bulma.io/images/placeholders/96x96.png"
alt="Placeholder image"
/>
</figure>
</div>
<div className="media-content" style={{ border: "1px grey" }}>
<p className="title is-5">{title}</p>
<p className="content">{description}</p>
<button className="button is-success">Edit</button>
<button
onClick={() => {
this.handleDelete(_id);
}}
className="button is-success"
>
Delete
</button>
</div>
</div>
</div>
</div>
);
}
}
const mapStateToProps = () => {
return {
nothing: "nothing",
};
};
const mapDispatchToProps = (dispatch) => {
return {
deletePost: (id) => {
dispatch(deletePost(id));
},
};
};
export default connect(mapStateToProps)(Cards);
deletePostAction
export const deletePost = (id) => {
return async (dispatch) => {
dispatch({ type: "DELETING_POST_START" });
axios
.delete(`http://localhost:3000/api/v1/posts/${id}/delete`)
.then(({ data }) => {
// as the post is being returned in data.post
// get that object and pass to data inside dispatch
const { post } = data;
dispatch({
type: "DELETING_POST_SUCCESS",
data: post,
});
})
.catch((error) => {
dispatch({
type: "DELETING_POST_FAILURE",
data: { error: "Something went wrong" },
});
});
};
};
答案 1 :(得分:0)
导出没有mapdispatchtoprops,请尝试类似的操作。对Post组件也要执行相同的操作
import React, { Component } from "react"
import { connect } from "react-redux"
import { deletePost } from "../actions/userActions"
class Cards extends Component {
handleDelete = (_id) => {
this.props.deletePostAction(_id)
}
render() {
const { _id, title, description } = this.props.post
return (
<div className="card">
<div className="card-content">
<div className="media">
<div className="media-left">
<figure className="image is-48x48">
<img
src="https://bulma.io/images/placeholders/96x96.png"
alt="Placeholder image"
/>
</figure>
</div>
<div className="media-content" style={{border: "1px grey"}}>
<p className="title is-5">{title}</p>
<p className="content">{description}</p>
<button className="button is-success">Edit</button>
<button onClick={() => {this.handleDelete(_id)}} className="button is-success">Delete</button>
</div>
</div>
</div>
</div>
)
}
}
const mapStateToProps = () => {
return {
nothing: "nothing"
}
}
const mapDispatchToProps = dispatch => ({
deletePostAction: () => dispatch(deletePost)
});
export default connect(mapStateToProps,mapDispatchToProps)(Cards)