我正在从文档中学习 redux,我正在尝试在添加 usersSlice 后添加新帖子,但阅读添加的新帖子时出错



我正在尝试添加一个新帖子。最初,代码运行良好,但在添加usersSlice并将用户与帖子关联后,我出现错误无法从PostList.js读取undefined的属性(读取"substring"(。下面是请帮助的代码。

postsSlice.js

import { createSlice, nanoid } from "@reduxjs/toolkit";
const initialState = [
{ id: "1", title: "First Post!", content: "Hello!" },
{ id: "2", title: "Second Post", content: "More text" }
];
const postsSlice = createSlice({
name: "posts",
initialState,
reducers: {
postAdded(state, action) {
state.push(action.payload);
},
prepare(title, content, userId) {
return {
payload: {
id: nanoid(),
title,
content,
user: userId
}
};
},
postUpdated(state, action) {
const { id, title, content } = action.payload;
const existingPost = state.find((post) => post.id === id);
if (existingPost) {
existingPost.title = title;
existingPost.content = content;
}
}
}
});
export const { postAdded, postUpdated } = postsSlice.actions;
export default postsSlice.reducer;

usersSlice.js

import { createSlice } from "@reduxjs/toolkit";
const initialState = [
{ id: "0", name: "Tianna Jenkins" },
{ id: "1", name: "Kevin Grant" },
{ id: "2", name: "Madison Price" }
];
const userSlice = createSlice({
name: "users",
initialState,
reducers: {}
});
export default userSlice.reducer;

store.js

import { configureStore } from "@reduxjs/toolkit";
import postsReducer from "../features/posts/postsSlice";
import usersReducer from "../features/users/usersSlice";
const store = configureStore({
reducer: {
posts: postsReducer,
users: usersReducer
}
});
export default store;

AddPostForm.js

import React, { useState } from "react";
import { postAdded } from "./postsSlice";
import { useDispatch, useSelector } from "react-redux";
export const AddPostForm = () => {
const [title, setTitle] = useState("");
const [content, setContent] = useState("");
const [userId, setUserId] = useState("");
const dispatch = useDispatch();
const users = useSelector((state) => state.users);
const onTitleChanged = (e) => setTitle(e.target.value);
const onContentChanged = (e) => setContent(e.target.value);
const onAuthorChanged = (e) => setUserId(e.target.value);

const onSavePostClicked = () => {
if (title && content) {
dispatch(postAdded(title, content, userId));
setTitle("");
setContent("");
}
};

const canSave = Boolean(title) && Boolean(content) && Boolean(userId);
const userOptions = users.map((user) => (
<option key={user.id} value={user.id}>
{user.name}
</option>
))
return (
<section>
<h2>Add New Post</h2>
<form>
<label htmlFor="postTitle">Post title</label>
<input
type="text"
id="postTitle"
name="postTitle"
value={title}
onChange={onTitleChanged}
/>
<label htmlFor="postAuthor">Author:</label>
<select id="postAuthor" value={userId} onChange={onAuthorChanged}>
<option value=""></option>
{userOptions}
</select>
<label htmlFor="postContent">Content:</label>
<textarea
id="postContent"
name="postContent"
value={content}
onChange={onContentChanged}
/>
<button type="button" onClick={onSavePostClicked} disabled={!canSave}>
Save Post
</button>
</form>
</section>
);
};

PostsList.js

import React from "react";
import { useSelector } from "react-redux";
import { Link } from "react-router-dom";
import { PostAuthor } from "./PostAuthor";
export const PostsList = () => {
const posts = useSelector((state) => state.posts);
const renderedPosts = posts.map((post) => (
<article className="post-exerpt" key={post.id}>
<h3>{post.title}</h3>
<p className="post-content">{post.content.substring(0, 100)}</p>
<PostAuthor userId={post.user} />
<Link to={`/posts/${post.id}`} className="button muted-button">
View Post
</Link>
</article>
));
return (
<section className="posts-list">
<h2>Posts</h2>
{renderedPosts}
</section>
);
};

PostAuthor.js

import React from "react";
import { useSelector } from "react-redux";
export const PostAuthor = ({ userId }) => {
const author = useSelector((state) =>
state.users.find((user) => user.id === userId)
);
return <span>by: {author ? author.name : "Unknown author"}</span>;
};

SinglePostPage.js

import React from "react";
import { useSelector } from "react-redux";
import { Link } from "react-router-dom";
import { PostAuthor } from "./PostAuthor";
export const SinglePostPage = ({ match }) => {
const { postId } = match.params;
const post = useSelector((state) =>
state.posts.find((post) => post.id === postId)
);
if (!post) {
return (
<section>
<h2>Post not found!</h2>
</section>
);
}
return (
<section>
<article className="post">
<h2>{post.title}</h2>
<PostAuthor userId={post.user} />
<p className="post-content">{post.content}</p>
<Link to={`/editPost/${post.id}`} className="button">
Edit Post
</Link>
</article>
</section>
);
};

中有几件事你做错了

  • 调度数据,您不必传递对象,在AddPostForm.js中只需执行以下操作(例如从文档中检查(

    dispatch(postAdded(title, content, userId));

  • 添加减速器的方式是错误的,应该如下(检查文档(

reducers: {
postAdded: {
reducer(state, action) {
state.push(action.payload);
},
prepare(title, content, userId) {
return {
payload: {
id: nanoid(),
title,
content,
user: userId
}
};
}
},....}

也添加了沙箱链接,请分叉并检查

相关内容

  • 没有找到相关文章

最新更新