Conversation
mikellewade
left a comment
There was a problem hiding this comment.
Solhee, nice work on your React Chatlog project!
| import { useState } from 'react'; | ||
|
|
||
| const App = () => { | ||
| const [messageData, setMessageData] = useState(messagesData); |
There was a problem hiding this comment.
Nice work on using the useState hook to initialize state for your App component.
| const toggleLiked = (messageId) => { | ||
| const messages = messageData.map(message => { | ||
| if (message.id === messageId) { | ||
| return { ...message, liked: !message.liked }; | ||
| } else { | ||
| return message; // message like status not changed | ||
| } | ||
| }); | ||
| setMessageData(messages); | ||
| }; |
There was a problem hiding this comment.
Great to see you using .map to map over your entries! Very functional! Since you are using a simple conditional block here, we could make this more succinct by using a ternary instead like so:
const toggleLike = (id) =>
setEntries(entries.map(entry =>
entry.id === id ? { ...entry, liked: !entry.liked } : entry
));When you find yourself with simple checks like these, more often than not a ternary could be implemented instead for conciseness but still maintaining readability.
| }); | ||
| setMessageData(messages); | ||
| }; | ||
| const totalLikes = messageData.filter(message => message.liked).length; |
There was a problem hiding this comment.
You could also do this with the.reduce method like so:
const totalLikes = chatMessages.reduce((count, message) => count + (message.liked ? 1 : 0), 0);| <header> | ||
| <h1>Application title</h1> | ||
| <h1>React Chatlog</h1> | ||
| <section id="heartWidget">{totalLikes} ❤️s</section> |
| <ChatLog | ||
| entries={messageData} | ||
| onLikeToggle={toggleLiked} | ||
| ></ChatLog> |
There was a problem hiding this comment.
Formatting your component like this is one way to maintain readability! ⭐️🫡
| ChatLog.propTypes = { | ||
| entries: PropTypes.arrayOf( | ||
| PropTypes.shape({ | ||
| sender: PropTypes.string.isRequired, | ||
| body: PropTypes.string.isRequired, | ||
| timeStamp: PropTypes.string.isRequired, | ||
| id: PropTypes.number, | ||
| liked: PropTypes.bool | ||
| }) | ||
| ).isRequired, | ||
| onLikeToggle: PropTypes.func | ||
| }; |
There was a problem hiding this comment.
Nice work including prop types for this component! Just a quick reminder: in React v19, PropTypes are deprecated. Moving forward, it's best to use TypeScript for type checking, as it's the recommended and more robust solution for ensuring type safety across your application.
| import PropTypes from 'prop-types'; | ||
|
|
||
| const ChatEntry = () => { | ||
| const ChatEntry = ({id, sender, body, timeStamp, liked, onLikeToggle}) => { |
There was a problem hiding this comment.
| const ChatEntry = ({id, sender, body, timeStamp, liked, onLikeToggle}) => { | |
| const ChatEntry = ({ id, sender, body, timeStamp, liked, onLikeToggle }) => { |
| const likeButtonClicked = () => { | ||
| onLikeToggle(id); | ||
| }; | ||
| const heartColor = liked ? '❤️' : '🤍'; |
| <h2 className="entry-name">{sender}</h2> | ||
| <section className="entry-bubble"> | ||
| <p>Replace with body of ChatEntry</p> | ||
| <p className="entry-time">Replace with TimeStamp component</p> | ||
| <button className="like">🤍</button> | ||
| <p>{body}</p> | ||
| <p className="entry-time"> | ||
| <TimeStamp time={timeStamp}></TimeStamp> |
| <p className="entry-time"> | ||
| <TimeStamp time={timeStamp}></TimeStamp> | ||
| </p> | ||
| <button className="like" onClick={likeButtonClicked}>{heartColor}</button> |
There was a problem hiding this comment.
The button function could also be implemented like so:
<button className='like' onClick={() => likeButtonClicked(id)}>{liked ? '❤️': '🤍'}</button>
No description provided.