我正在 NextJS 中构建一个 mdx 博客。为此,我在 lib 下的 posts.js 中创建了一个函数 getPostDataByCategory(category) 来根据类别过滤帖子。
getPostDataByCategory(category) {
const fileNames = fs.readdirSync(postsDirectory);
// allPostsData to read all the file contents parsed using gray-matter
const allPostsData = fileNames.map((fileName) => {
...
}
let filteredPosts = [];
filteredPosts.push(
allPostsData.filter((post) => post.categories.includes(category))
);
return { filteredPosts };
}
我在categories/[categories].js中的getStaticProps中收到filteredPosts,如下:
export async function getStaticProps({ params }) {
let posts = await getPostDataByCategory(params.categories);
const filteredPosts = JSON.parse(JSON.stringify(posts));
return {
props: {
filteredPosts,
},
};
}
此后,我收到类别中过滤后的帖子:
export default function Category({ filteredPosts }) {
return (
<Layout>
<ul>
{filteredPosts.map((posts) => (
<li key={posts.slug}>
<p>{posts.title}</p>
</li>
))}
</ul>
</Layout>
);
}
但是它给了我一个错误TypeError:filteredPosts.map不是一个函数
我理解这个错误是由于filteredPosts不是一个数组,并且必须完成对象破坏或者必须将其转换为数组。
如有任何帮助,我们将不胜感激。预先感谢。
我广泛搜索了将对象数组转换为数组数组的方法,但它们对于我的用例来说似乎都很复杂。必须有一种更简单的方法来做到这一点。
您混淆了对象键名称,并将嵌套数组推送到不需要的地方,从而导致映射操作混乱和问题。大多数修复都可以对
getPostDataByCategory
进行,以清理您的日期结构。
首先,
.filter()
方法返回一个新数组,因此下面的代码表示将一个数组(由 filter()
返回的数组)推入 filteredPosts
数组中:
let filteredPosts = [];
filteredPosts.push(
allPostsData.filter((post) => post.categories.includes(category)) // push a new array into th `fileredPosts` array
);
这最终会导致您拥有嵌套数组,这不是您想要的。您只需将
fileredPost
直接分配给 .filter()
的结果即可:
const filteredPosts = allPostsData.filter((post) => post.categories.includes(category));
接下来,您将使用
filteredPosts
键返回一个对象:
return { filteredPosts };
这相当于返回一个对象,如下所示:
return { filteredPosts: filteredPosts};
因此,您的对象有一个
filteredPosts
posts key,它保存 filteredPosts
变量中的数组。由于您只返回一件事(即:过滤后的帖子),因此您可以避免创建对象,以便现在您的 getPostDataByCategory
返回一个数组:
return filteredPosts;
对
getPostDataByCategory
进行这些更改后,您现在可以更新 getStaticProps
的使用方式(请参阅代码注释):
export async function getStaticProps({ params }) {
const filteredPosts = getPostDataByCategory(params.categories); // you don't need to `await` the `getPostDataByCategory()` as it isn't `async` and doesn't return a Promise.
// No need to create a deep copy: const filteredPosts = JSON.parse(JSON.stringify(posts));
return {
props: {
filteredPosts, // filteredPosts is now an array of objects
},
};
}
现在您可以像您尝试做的那样正确映射您的
filteredPosts
:
{filteredPosts.map((posts) => (
<li key={posts.slug}>
<p>{posts.title}</p>
</li>
))}