Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Develop #2930

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open

Develop #2930

wants to merge 10 commits into from

Conversation

djtyrf312
Copy link

src/App.tsx Outdated

const todosWithUser: TodoWithUser[] = todosFromServer.map(
(todo): TodoWithUser => {
const user = usersFromServer.find(({ id }) => id === todo.userId) as User;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand that this is for TS purposes.
But what if the user with the provided id is not found? Shit like that sometimes happens and we want to handle it instead of casting types

src/App.tsx Outdated
const [userId, setUserId] = useState(defaultUserId);
const [hasTitleError, setHasTitleError] = useState(false);
const [hasUserError, setHasUserError] = useState(false);
const isNotSelectedUser = userId === defaultUserId;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when we're dealing with booleans, we usually make the logic from positive, e.g. isSelectedUser, and use with NOT (!) operator.

It is difficult to read stuff like !isNotSelectedUser, since I have to compile in my mind what this variable means. In my mind it would sound like not is not selected user, this is difficult to read

src/App.tsx Outdated
const [hasUserError, setHasUserError] = useState(false);
const isNotSelectedUser = userId === defaultUserId;
const hasForbiddenSymbolsInTitle = !validateTitle(title);
const titleErrorMessage = hasForbiddenSymbolsInTitle

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

from this thing, it looks like there must be some error message anyway. Would be better to have it as a function, which can also return null if there's no error


if (title && !isNotSelectedUser) {
const user = usersFromServer.find(({ id }) => id === +userId) as User;
const newId = Math.max(...todos.map(todo => todo.id)) + 1;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you don't have to use spread operator here, since map is not mutable

Copy link
Author

@djtyrf312 djtyrf312 Jan 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without this, I would have an error with the types. So maybe better to leave it to split the array to separate arguments for math max
image

src/App.tsx Outdated
}

if (title && !isNotSelectedUser) {
const user = usersFromServer.find(({ id }) => id === +userId) as User;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

converting to a number with + is not a mistake, but not considered a clean approach. To make it easier to understand we usually convert the type explicitly, like Number(userId)

userId: +userId,
id: newId,
title,
completed: false,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isCompleted would be a cleaner approach

src/App.tsx Outdated
setHasTitleError(false);
}}
/>
{hasTitleError && <span className="error">{titleErrorMessage}</span>}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this thing is difficult to read since there's a lot of stuff happening. There's a render condition, tag name, classname, text node.

Here's how I would approach it:

Suggested change
{hasTitleError && <span className="error">{titleErrorMessage}</span>}
{hasTitleError && (
<span className="error">
{titleErrorMessage}
</span>
)}

src/App.tsx Outdated
Comment on lines 107 to 113
{usersFromServer.map(user => {
return (
<option key={user.id} value={user.id}>
{user.name}
</option>
);
})}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can return right away instead of return statement if there's no logic happening inside the callback

Suggested change
{usersFromServer.map(user => {
return (
<option key={user.id} value={user.id}>
{user.name}
</option>
);
})}
{usersFromServer.map(user => (
<option key={user.id} value={user.id}>
{user.name}
</option>
)
)}

todos: TodoWithUser[];
};

export const TodoList = ({ todos }: Props) => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mentioned return-right-away approach somewhere above, this component is a great place to practice it, since we have 2 return statement that can be avoided here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants