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

PR for react-chatlog instructor review #44

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

yangashley
Copy link

No description provided.

@yangashley
Copy link
Author

FYI @SalmaAnany the link you submitted in Learn wasn't to a valid PR, so I opened this so I can add review comments to it.

Copy link
Author

@yangashley yangashley left a comment

Choose a reason for hiding this comment

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

Let me know if you have any questions about my review comments.

src/App.jsx Outdated
Copy link
Author

Choose a reason for hiding this comment

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

App.jsx should have the following (you can reference examples of how we did this in flasky-front-end, review this link here):

  • function to calculate the number of likes from each ChatEntry (see lines 83-87 and lines 89, 95 in App.jsx in the link above)
  • state that represents all the messages (see line 42 in App.jsx in the link above)
  • an event handling function that updates the state when a message is liked or unliked so the page can re-render that is passed down as a prop to ChatLog.jsx and then down to ChatEntry.jsx (see lines 44-55 and line 98 in App.jsx in the link above)

import TimeStamp from './TimeStamp.jsx';

const ChatEntry = ({sender,body,timeStamp, liked, numOfLikes, setLikes, isLocal}) => {
const [like, setLike] = useState(liked);
Copy link
Author

Choose a reason for hiding this comment

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

We don't need to track if a ChatEntry has been liked with state here.

If App.jsx knows about all the components (which is why we lift state out of ChatEntry and up to App), then we can get rid of state here.

See how the Cat.jsx component is structured here. We can think of Cat as being equivalent to ChatEntry.

Comment on lines 15 to 22
<button className="like" onClick={() =>{
if (like === true) {
setLike(false);
setLikes(numOfLikes - 1);
} else {
setLike(true);
setLikes(numOfLikes + 1);
}
Copy link
Author

Choose a reason for hiding this comment

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

Instead of onClick being an anonymous function with logic, I'd expect the onClick event handler to invoke a function that is passed down from App.jsx to ChatLog.jsx and finally down to this component here ChatEntry.jsx.

You can find an example of what this looks like at this link, see lines 17-21 and line 35 in Cat.jsx

Petting a cat in flasky-front-end is the equivalent of liking a ChatEntry.

{`${numOfLikes} ❤️s`}
</div>
{
entries?.map(i => <ChatEntry key={i.id} body={i.body} sender={i.sender} timeStamp={i.timeStamp} liked={i.liked} numOfLikes={numOfLikes} setLikes={setLikes}
Copy link
Author

Choose a reason for hiding this comment

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

This line is challenging to read and violates the JS styleguide that suggests each line is no more than 120 characters long.

Using new lines for each prop being passed would help with readability.

Copy link
Author

Choose a reason for hiding this comment

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

Prefer a more descriptive name than i. Maybe entry?

const [numOfLikes, setLikes] = useState(entries?.filter(i => i.liked === true)?.length);
return <div>
<div>
{`${numOfLikes} ❤️s`}
Copy link
Author

Choose a reason for hiding this comment

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

This element should live in App.jsx, at the highest level of the hierarchy of all the components.

You can see an example of how this looks in App.jsx on line 95 here in flasky-front-end

Copy link
Author

@yangashley yangashley left a comment

Choose a reason for hiding this comment

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

Your refactored project looks great!


const App = () => {
const [chatEntries, setChatEntries] = useState(data);
Copy link
Author

Choose a reason for hiding this comment

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

👍

setChatEntries(updatedEntries);
};

const totalLikes = chatEntries.filter((entry) => entry.liked).length;
Copy link
Author

Choose a reason for hiding this comment

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

You could also use reduce too:

  // adding a bool to a number treats true as 1 and 0 as false
  const totalLikes = chatEntries.reduce((totalLikes, entry) => (totalLikes + entry.liked), 0);

Comment on lines +31 to +32
entries={chatEntries}
onToggleLike={toggleLike}
Copy link
Author

Choose a reason for hiding this comment

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

Yep, exactly the props that need to get passed down.

Comment on lines +4 to +21
const ChatLog = ({ entries, onToggleLike }) => {
return (
<div>
{entries.map((entry) => (
<ChatEntry
key={entry.id}
id={entry.id}
body={entry.body}
sender={entry.sender}
timeStamp={entry.timeStamp}
liked={entry.liked}
onToggleLike={onToggleLike}
isLocal={entry.sender === 'Vladimir'}
/>
))}
</div>
);
};
Copy link
Author

Choose a reason for hiding this comment

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

Typically you'll see the result of using map referenced by a variable and using that variable in the JSX, like:

  const chatLogs =  entries.map((entry) => {
	      return (
	          <ChatEntry                                 
	            key={entry.id}
                    {...entry}
                    onLikeToggle={onLikeToggle}
                    isLocal={entry.sender === 'Vladimir'}
	          />
	        );
	     });
  };

  return (
        <div>
            {chatLogs}
        </div>
  );

</p>
<button
className="like"
onClick={handleLikeClick}
Copy link
Author

Choose a reason for hiding this comment

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

👍

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