scrimba
React Challenges
Read-Me-Later: Challenge
Go Pro!Bootcamp

Bootcamp

Study group

Collaborate with peers in your dedicated #study-group channel.

Code reviews

Submit projects for review using the /review command in your #code-reviews channel

Read-Me-Later: Challenge
AboutCommentsNotes
Read-Me-Later: Challenge
Expand for more info
App.jsx
run
preview
console
import React from "react"
import { nanoid } from "nanoid"
import Header from "./components/Header"
import Article from "./components/Article"
import archivedArticles from "./data/archivedArticles"
import favoritedArticles from "./data/favoritedArticles"
import savedArticles from "./data/savedArticles"
import trashedArticles from "./data/trashedArticles"

export default function App() {
const [articleQueue, setArticleQueue] = React.useState(savedArticles)

const stats = getStats()

const articleComponents = articleQueue.map((articleData) => {
return <Article articleData={articleData} key={articleData.id} />
})

const noArticlesMessage = <p className="no-articles-message">There are no articles to show.</p>

function getStats() {
return {
numOfFavorites: favoritedArticles.length,
numOfArchived: archivedArticles.length,
numOfTrashed: trashedArticles.length,
}
}

function getTargetArticle(id) {
return savedArticles.find((item) => item.id === id)
}

function removeFromSavedArticles(targetArticle) {
const targetIndex = savedArticles.indexOf(targetArticle)
savedArticles.splice(targetIndex, 1)
}


/*-----State Setting Functions-------------------------------------------*/

function favorite(id) {
const targetArticle = getTargetArticle(id)
if (favoritedArticles.includes(targetArticle)) {
const targetIndex = favoritedArticles.indexOf(targetArticle)
favoritedArticles.splice(targetIndex, 1)
} else {
favoritedArticles.push(targetArticle)
}
setArticleQueue([...savedArticles])
}

function archive(id) {
const targetArticle = getTargetArticle(id)
removeFromSavedArticles(targetArticle)
archivedArticles.push(targetArticle)
setArticleQueue([...savedArticles])
}

function trash(id) {
const targetArticle = getTargetArticle(id)
removeFromSavedArticles(targetArticle)
if (favoritedArticles.includes(targetArticle)) {
const targetIndex = favoritedArticles.indexOf(targetArticle)
favoritedArticles.splice(targetIndex, 1)
}
trashedArticles.push(targetArticle)
setArticleQueue([...savedArticles])
}

function toggleExpand(id) {
const targetArticle = getTargetArticle(id)
targetArticle.expanded = !targetArticle.expanded
setArticleQueue(savedArticles)
}

/*-------------------------------------------------------------------------*/

/* Challenge

The four buttons for each article aren't working. Your task is to set them up as follows:

1. You should add a single onClick event handler to the "articles-container" div. No other event handlers should be added to the project. The event handler should use the buttons'
"button-type" and "article-id" data attributes to do the following:

if the button's Then use the button's
"button-type" "article-id" data value
data value is: to do the following:
╷---------------------╷-----------------------------╷
| "favorite" | favorite(idValue) |
|---------------------|-----------------------------|
| "archive" | archive(idValue) |
|---------------------|-----------------------------|
| "trash" | trash(idValue) |
|---------------------|-----------------------------|
| "toggleExpand" | toggleExpand(idValue) |
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
idValue = the value of the "article-id" data attribute.
This is just for illustrative purposes — you don't have to
name it this way!

2. The first three functions listed above already work and should not be changed. However,
the toggleExpand function (line 70) is currently broken and must be fixed. You *just* need to make a very small (but important) change to fix it! Try to identify and articulate what exactly the issue was and why your solution fixed it.

3. Your code for the event handler should be as concise and DRY (Don't Repeat Yourself) as
possible, while maintaining readability.

4. You should test the app to make sure it's working correctly. After completing the
above tasks, an article should expand when you click the expand button, the heart-shaped favorite button should toggle on and off when you click it, and the article should disappear if you click the archive or trash button. The numbers at the top of the app should also reflect the number of articles you've favorited, archived, or trashed.

Bonus Challenge: Even though the four functions listed above will work the way they're set up (after you fix the fourth one), there s something unorthodox and arguably "wrong" going on with them — something the React Documentation warns against. See if you can figure out what it is!

*/

return (
<div className="wrapper">
<Header stats={stats} setArticleQueue={setArticleQueue} />
<div className="articles-container">
{articleQueue.length > 0 ? articleComponents : noArticlesMessage}
</div>
</div>
)
}
Console
/index.html#
-4:03