Skip to content

crow-lexy#15

Open
xixilele1990 wants to merge 2 commits intoAda-C24:mainfrom
xixilele1990:main
Open

crow-lexy#15
xixilele1990 wants to merge 2 commits intoAda-C24:mainfrom
xixilele1990:main

Conversation

@xixilele1990
Copy link
Copy Markdown

No description provided.

Copy link
Copy Markdown

@kelsey-steven-ada kelsey-steven-ada left a comment

Choose a reason for hiding this comment

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

Great work! Let me know if you have any questions on the feedback below =]

Comment thread src/App.jsx
);
};

const totalLikes = entries.reduce((acc, entry) => acc + Number(entry.liked), 0);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Great use of the existing data and array.reduce to calculate the total likes!

Comment thread src/App.jsx
Comment on lines +9 to +15
const handleLike = (id) => {
setEntries((prevEntries) =>
prevEntries.map((entry) =>
entry.id === id ? { ...entry, liked: !entry.liked } : entry
)
);
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Nice work ensuring we're creating a new array of messages to trigger the re-render after updating the liked value!

Comment on lines +8 to +11
const handleLikeClick =
typeof onHandleLike === 'function'
? () => onHandleLike(message.id)
: undefined;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

It is generally considered against best practices to create a function we will be passing to children components inside of the mapping function itself.

Thinking about the single responsibility principle: we are doing two things at once by both defining functionality for a button press and mapping over entries to create a list of components.

Looking at the principles of encapsulation and packaging related code in the same file: the functionality for handleLikeClick seems tied to the ChatEntry component. ChatLog defines this function but never uses it itself, it only references the function to pass it to ChatEntry.

How can we refactor this code so that we are not defining functionality inside of a mapping function and so that the code lives with the component that will use it?

Comment thread src/App.jsx
const handleLike = (id) => {
setEntries((prevEntries) =>
prevEntries.map((entry) =>
entry.id === id ? { ...entry, liked: !entry.liked } : entry
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I like this pattern of sending just the id to handleLike since it keeps all the state management and message object creation confined to App.

Comment on lines +14 to +16
<p className="entry-time">
<TimeStamp time={timeStamp} />
</p>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Great thought to wrap this in a p element since TimeStamp returns a span as the outer element!

Comment on lines +17 to +19
<button className="like" onClick={onHandleLike}>
{heart}
</button>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

We can increase the accessibility of our page by setting further attributes on elements, especially interactive elements. Below is an example of updates we could make to the button, check out the MDN docs for more info!

<button
  onClick={onHandleLike}
  className="like"
  aria-label={heart}
  role="img"
>
  {heart}
</button>

Comment on lines +10 to +11
<article className="chat-entry local">
<h2 className="entry-name">{sender}</h2>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

If we wanted to apply the optional enhancements to align the chat bubbles, we could use a ternary operator to decide the remote or local className based on the sender. Then we could use an interpolated string to create the className which always holds chat-entry along with a placeholder where we pass the variable holding the remote or local class name.

: undefined;

return (
<li key={message.id}>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Great use of the unique message ids for the key value!



ChatLog.propTypes = {
entries: PropTypes.arrayOf(PropTypes.shape({
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Great use of Prop-Types and flagging those necessary for render with isRequired, I love the use of PropTypes.shape to ensure the passed array has the necessary contents as well!

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