implementation#2037
Conversation
mateacademy-ai-mentor
left a comment
There was a problem hiding this comment.
Review Summary
Hello! You've done a great job structuring the components and implementing the core rendering logic. However, some changes are needed to meet all the project requirements before this can be approved.
There are a few critical issues to address:
- Project Structure: All type definitions (
Post,User,Comment) must be moved from the component folders to the required./src/types/directory. The task explicitly requires this centralized structure for types. - Potential Runtime Error: In
src/App.tsx,users.find(...)can returnundefinedif a user isn't found for a given post. This can crash the application since thePosttype expects aUserobject, notundefined. Please add logic to handle cases where a user might not be found to prevent this error.
Addressing these points will bring your solution into full compliance with the task requirements. Keep up the good work!
✨ Please rate this review in the Platform's notification center1. I will be grateful for your feedback! ✨
Important
Fix the issues, commit the changes, and then re-request my review using the Re-request review button2 in the Reviewers tab.
Tip
If you have any comments about this review, please leave a message in the Add a comment section below and mention me with the @mateacademy-ai-mentor tag3.
I will read your message during my next review of your pull request. Please do not reply directly to my comments, as that feature is not supported yet.
Caution
Do not close the pull request until the review is complete. Closing it early can lead to unexpected behavior and disrupt the review process.
Footnotes
| import { Post } from './components/PostInfo/Post'; | ||
| import { Comment } from './components/CommentInfo/Comment'; | ||
| import { User } from './components/UserInfo/User'; |
There was a problem hiding this comment.
According to the task description, all types should be created in the ./src/types/ directory. These type definitions should be moved there from the component folders, and the imports updated accordingly.
| const comments: Comment[] = commentsFromServer; | ||
| const users: User[] = usersFromServer; | ||
|
|
||
| postsFromServer.map(postFromServer => { |
There was a problem hiding this comment.
The map function is intended to create a new array based on the transformation of each element of the original array. Using it here with posts.push to modify an external array is an unconventional use of map. A more idiomatic approach would be to declare and initialize posts with the result of this map operation.
|
|
||
| postsFromServer.map(postFromServer => { | ||
| posts.push({ | ||
| user: users.find(user => user.id === postFromServer.userId), |
There was a problem hiding this comment.
The find method returns undefined if no user matches the userId. The Post type, however, expects the user property to be of type User, not User | undefined. This could cause a runtime error in child components if a post's user is not found. Please consider how to handle this possibility.
| export interface Comment { | ||
| postId: number; | ||
| id: number; | ||
| name: string; | ||
| email: string; | ||
| body: string; | ||
| } |
There was a problem hiding this comment.
According to the task description, all types should be created in the ./src/types/ directory. This Comment interface should be moved to a file within that directory, for example, src/types/Comment.ts.
| <div className="CommentInfo"> | ||
| <div className="CommentInfo__title"> | ||
| <strong className="CommentInfo__name">{comment.name}</strong> | ||
| {' by '} |
There was a problem hiding this comment.
This violates checklist item #5: 'Use string interpolation inside tag content'. While not strictly interpolation, wrapping static text in {} is unnecessary here. You can write the text directly between components, for example: ...</strong> by <a.... This makes the code cleaner.
| <div className="PostInfo__header"> | ||
| <h3 className="PostInfo__title">{post.title}</h3> | ||
| <p> | ||
| {' Posted by '} |
There was a problem hiding this comment.
This violates checklist item #5: 'Use string interpolation inside tag content'. For static text like this, you can write it directly inside the <p> tag without the curly braces and quotes. For example: <p>Posted by <UserInfo ... /></p>.
| export interface User { | ||
| id: number; | ||
| name: string; | ||
| username: string; | ||
| email: string; | ||
| } |
There was a problem hiding this comment.
According to the task description, all types should be created in the ./src/types/ directory. This User interface should be moved to a file within that directory, for example, src/types/User.ts.
| export interface Post { | ||
| user: User; | ||
| id: number; | ||
| title: string; | ||
| body: string; | ||
| comments: Comment[]; | ||
| } |
There was a problem hiding this comment.
According to the task description, all types should be created in the ./src/types/ directory. This Post interface should be moved to a file within that directory, for example, src/types/Post.ts.
| @@ -1,3 +1,11 @@ | |||
| import React from 'react'; | |||
| import { Post } from '../PostInfo/Post'; | |||
There was a problem hiding this comment.
According to the task description, all types should be created in the ./src/types/ directory. The Post type should be moved to a file within that directory (e.g., src/types/Post.ts) and imported from there.
| @@ -1,3 +1,14 @@ | |||
| import React from 'react'; | |||
| import { User } from './User'; | |||
There was a problem hiding this comment.
According to the task description, all types should be created in the ./src/types/ directory. The User type should be moved to a file within that directory, and this import should be updated to point to it.
mateacademy-ai-mentor
left a comment
There was a problem hiding this comment.
Review Summary
Great job addressing the major issues from the last review, especially with moving the types and handling missing users! The application is much more robust now. However, a few changes are needed to meet all the project requirements before this can be approved.
The most critical issue is that the styles have not been split into component-specific files as required by the task. Please move the relevant styles from App.scss into files like PostList.scss, UserInfo.scss, etc.
Additionally, please address these checklist violations:
- In
App.tsx, thefindUserfunction should be renamed tofindUserByIdto be more descriptive [CHECKLIST ITEM #6]. - In
PostInfo.tsxandCommentInfo.tsx, please use template literals for strings like{' by '}to comply with [CHECKLIST ITEM #5].
Lastly, for best practices, please wrap the returned arrays in PostList.tsx and CommentList.tsx with a React Fragment (<>...</>) and refactor the .map() in App.tsx to return a new array instead of using .push().
✨ Please rate this review in the Platform's notification center1. I will be grateful for your feedback! ✨
Important
Fix the issues, commit the changes, and then re-request my review using the Re-request review button2 in the Reviewers tab.
Tip
If you have any comments about this review, please leave a message in the Add a comment section below and mention me with the @mateacademy-ai-mentor tag3.
I will read your message during my next review of your pull request. Please do not reply directly to my comments, as that feature is not supported yet.
Caution
Do not close the pull request until the review is complete. Closing it early can lead to unexpected behavior and disrupt the review process.
Footnotes
| const comments: Comment[] = commentsFromServer; | ||
| const users: User[] = usersFromServer; | ||
|
|
||
| function findUser(usersToCheck: User[], id: number): User { |
There was a problem hiding this comment.
This violates checklist item #6: 'If you are searching some entity by some filter, specify it in function/method name'. Since this function finds a user by their id, a more descriptive name would be findUserById.
| return user; | ||
| } | ||
|
|
||
| postsFromServer.map(postFromServer => { |
There was a problem hiding this comment.
Using Array.prototype.map() for side effects like posts.push() is generally considered an anti-pattern. The purpose of .map() is to create a new array from an existing one. A better approach is to use .map() to return a new array and assign it directly to the posts constant. This avoids mutating an external array and makes the code more declarative.
| return comments.map(comment => ( | ||
| <CommentInfo key={comment.id} comment={comment} /> | ||
| )); |
There was a problem hiding this comment.
While React can render an array of elements, a component typed as React.FC is expected to return a single ReactElement or null. Returning an array directly from .map() doesn't conform to this type signature.
To ensure your component returns a single valid element, please wrap the result of the .map() function in a React Fragment (<>...</>).
| }; | ||
|
|
||
| export const PostList: React.FC<Props> = ({ posts }) => { | ||
| return posts.map(post => <PostInfo key={post.id} post={post} />); |
There was a problem hiding this comment.
A component typed as React.FC should return a single ReactElement or null. Returning an array of elements directly from .map() doesn't strictly adhere to this type. To fix this, you can wrap your mapped list in a React Fragment (<>...</>), which provides a single root element without adding an extra node to the DOM.
mateacademy-ai-mentor
left a comment
There was a problem hiding this comment.
Review Summary
I am approving this pull request as an educational override to help you progress, but please review the feedback below for future tasks. You've done an excellent job splitting the styles into component-specific files and improving the project structure!
Here are a few key areas for improvement:
- Component Encapsulation: In
PostList.tsxandCommentList.tsx, it's best practice for list components to render their own container<div>. This makes them self-contained and easier to style. - Using
.map()correctly: InApp.tsx,.map()should be used to return a new array, not to push items into an existing one. The correct approach is more declarative:const posts = postsFromServer.map(...). - String Interpolation: Remember to use template literals like
{` by `}instead of{' by '}inPostInfo.tsxandCommentInfo.tsxfor consistency [CHECKLIST ITEM #5].
Keep up the great work, and try to apply this feedback in your next tasks!
✨ Please rate this review in the Platform's notification center1. I will be grateful for your feedback! ✨
Footnotes
| postsFromServer.map(postFromServer => { | ||
| posts.push({ | ||
| user: findUserById(users, postFromServer.userId), | ||
| id: postFromServer.id, | ||
| title: postFromServer.title, | ||
| body: postFromServer.body, | ||
| comments: comments.filter(comment => comment.postId === postFromServer.id), | ||
| }); | ||
| }); |
There was a problem hiding this comment.
While this works, using .map() to cause side effects (like .push() into an external array) is considered an anti-pattern. The purpose of .map() is to create and return a new array.
It would be better to define the posts constant directly with the result of the map function, like this:
const posts: Post[] = postsFromServer.map(postFromServer => ({
user: findUserById(users, postFromServer.userId),
// ... other properties
}));This avoids mutating an array and makes the code more declarative.
| <div className="CommentInfo"> | ||
| <div className="CommentInfo__title"> | ||
| <strong className="CommentInfo__name">{comment.name}</strong> | ||
| {' by '} |
There was a problem hiding this comment.
This violates checklist item #5: 'Use string interpolation inside tag content'. As mentioned in the previous review, please use a template literal for string fragments like this. For example: {` by `}.
| return comments.map(comment => ( | ||
| <CommentInfo key={comment.id} comment={comment} /> | ||
| )); |
There was a problem hiding this comment.
This component returns an array of CommentInfo components, which is valid. However, the styles for .CommentList (defined in CommentList.scss) are currently applied by a div in the parent PostInfo component.
For better encapsulation, the CommentList component should render its own root element with className="CommentList". This change will make the component self-contained and ensure that the "No comments yet" message also appears inside the styled container, which is not the case currently.
| }; | ||
|
|
||
| export const PostList: React.FC<Props> = ({ posts }) => { | ||
| return posts.map(post => <PostInfo key={post.id} post={post} />); |
There was a problem hiding this comment.
While returning an array of components is valid, it's better for a list component like this to render its own container element (e.g., a <div>). This practice improves component encapsulation, making it easier to style and manage. Please wrap the returned array in a container element.
| <div className="PostInfo__header"> | ||
| <h3 className="PostInfo__title">{post.title}</h3> | ||
| <p> | ||
| {' Posted by '} |
There was a problem hiding this comment.
This violates checklist item #5: 'Use string interpolation inside tag content'. As mentioned in the previous review, it's better to use a template literal for consistency and readability. Please change this to {` Posted by `}.
No description provided.