FAQ: React Styles - Review

This community-built FAQ covers the “Review” exercise from the lesson "React Styles ".

Paths and Courses
This exercise can be found in the following Codecademy content:

Front-End Development
Create an Advanced Web App with React and Redux
Front-End Engineer
Full-Stack Engineer
Front-End Development

Learn React
Learn React: Additional Basics

FAQs on the exercise Review

There are currently no frequently asked questions associated with this exercise – that’s where you come in! You can contribute to this section by offering your own questions, answers, or clarifications on this exercise. Ask or answer a question by clicking reply (reply) below.

If you’ve had an “aha” moment about the concepts, formatting, syntax, or anything else with this exercise, consider sharing those insights! Teaching others and answering their questions is one of the best ways to learn and stay sharp.

Join the Discussion. Help a fellow learner on their journey.

Ask or answer a question about this exercise by clicking reply (reply) below!
You can also find further discussion and get answers to your questions over in Language Help.

Agree with a comment or answer? Like (like) to up-vote the contribution!

Need broader help or resources? Head to Language Help and Tips and Resources. If you are wanting feedback or inspiration for a project, check out Projects.

Looking for motivation to keep learning? Join our wider discussions in Community

Learn more about how to use this guide.

Found a bug? Report it online, or post in Bug Reporting

Have a question about your account or billing? Reach out to our customer support team!

None of the above? Find out where to ask other questions here!

Hey there.

The solution for this exercise doesn’t work.

I cannot make the code work either.

Same here! frustrating!!!

Not sure why my codes not working, any advice?

HighScore.js:

import React from 'react';
import { highScores } from './highScoreData';

function HighScore() {
  const playerData = highScores.map((player) => 
    <li>Name: {player.username}</li>
    <li>Date: {player.date}</li>
    <li>Score: {player.score}</li>
  )

  return <ul>{playerData}</ul>
}

export default HighScore;

App.js:

import React from 'react';
import TitleScreen from './TitleScreen';
import HighScore from './HighScore'

function App() {
  return (
    <>
      <TitleScreen />
      <HighScore />
    </>
  );
}

export default App;

The problem seems to be with the map statement.

The map method returns an array (which is perfectly fine and not an issue). The map method will execute the callback function for each player in highScores. Whatever value is returned by the callback function (for each player) will be pushed to the new array being populated by the map method. You are using an arrow function (with implicit return) as the callback function. But you have three separate <li> elements. So, an implicit return will not capture all three elements. If you use curly braces for the body of the arrow function and do an explicit return, again you can’t return three separate elements. The elements need to be wrapped in a single element. I think a <ul> may be appropriate, but it is your choice. If you wrap the three <li> elements in a <ul> element, then you can EITHER do an implicit return OR use curly braces with an explicit return.

With the above proposed modification, you don’t need

return <ul>{playerData}</ul>

You could just return the array.

IMPLICIT RETURN FROM ARROW FUNCTION

function HighScore() {
  const playerData = highScores.map((player) =>
    <ul> 
        <li>Name: {player.username}</li>
        <li>Date: {player.date}</li>
        <li>Score: {player.score}</li>
     </ul>
  )

  return playerData;
}

EXPLICIT RETURN FROM ARROW FUNCTION
(Curly braces needed for body of function. return keyword needed for explicit return)

function HighScore() {
  const playerData = highScores.map((player) => {
    return (
    <ul> 
        <li>Name: {player.username}</li>
        <li>Date: {player.date}</li>
        <li>Score: {player.score}</li>
     </ul>
    )
  }
  )
  
  return playerData;
}
1 Like

Works also this:

function HighScore() { const listItems = highScores.map((player) => ( <li key={player.username}> <p>{player.username}</p> <p>{player.date}</p> <p>{player.score}</p> </li> )); return <ul>{listItems}</ul>; }

I’m a bit confused why my practice code isn’t working. I reviewed the cheatsheet and this seems to stick to the pattern. State is handled by the separate highScoreData.js file so there’s no need for HighScore to be anything but presentational. highScoreData is passed via props from App.js. What am I missing?

Here’s HighScore.js:

import React from 'react'; function HighScore (scoreData) { scoreData.forEach((score) => { return ( <> <h3>{score.userName}</h3> <p>{score.date}</p> <p>{score.score}</p> </> ); } } export default HighScore;

And App.js:

import React from 'react'; import TitleScreen from './TitleScreen'; import HighScore from './HighScore'; import highScores from './highScoreData'; function App() { return ( <> <TitleScreen /> <HighScore scoreData={highScores} /> </> ); } export default App;

Here are a number of issues you may wish to explore:

  • Firstly, in highScoreData.js, we have a named export in the form
export const highScores = [ { ...

Since this is a named export as opposed to a default export, therefore the import statement must be adjusted accordingly.
For a named export,

// You wrote:
import highScores from './highScoreData';

// It should be:
import { highScores } from './highScoreData';

Alternatively, you could leave the import statement unchanged and instead edit highScoreData.js to do a default export,

const highScores = [ { ... ]

export default highScores;

See the documentation for more on named and default exports: export - JavaScript | MDN

  • In HighScore.js, you have a missing closing parenthesis. You are missing a closing parenthesis ) just before the very last curly brace. That is why in the Codebyte you posed for HighScore.js, there is a red error mark.

  • When we create an instance of a component and provide props at the time of instantiation, then those props are sent to the component in the form of an object. When you tried to create an instance of HighScore, you wrote:

<HighScore scoreData={highScores} />

The HighScore component will actually receive a props object in which one of the properties will be scoreData. To extract this property from the object and assign to a variable, we need to do object destructuring. In HighScore.js,

// You wrote:
function HighScore (scoreData) {

// It should be:
function HighScore ({scoreData}) {

This will find the props.scoreData property and assign it a variable called scoreData. Within the function, we can then simply use the variable scoreData to access the provided information. To learn more about Object Destructuring, have a look at: Destructuring assignment (in particular have a look at the section titled “Object Destructuring”).

// With Object Destructuring,
function HighScore ({scoreData}) {

// Without Object Destructuring,
function HighScore (props) {
    scoreData = props.scoreData;
    ...
  • In HighScore.js, you are missing the return keyword,
// You wrote:
function HighScore ({scoreData}) {
  scoreData. ...

// It should be:
function HighScore ({scoreData}) {
  return scoreData. ...
  • You chose to use the forEach method to iterate over scoreData. But the forEach method’s
    return value (see documentation) is undefined. The forEach method executes a function once for every element of the array. So, in your case for every array element of scoreData, it will create a Fragment consisting of <h3> and two <p> elements. And then just throw away the fragment without doing anything useful.
    Instead of forEach, you want to use the map method. As the documentation explains, the map method’s return value is:

A new array with each element being the result of the callback function.

Therefore, using the map method on scoreData will result in an array of the form,

[ <> <h3>...</h3><p>...</p><p>...</p> </>, 
<> <h3>...</h3><p>...</p><p>...</p> </>,
<> <h3>...</h3><p>...</p><p>...</p> </>  ]

The map method will iterate over each element of the scoreData array, execute the callback function creating a Fragment, the Fragment will then be pushed to a new array. After the map method finishes, the new array (with fragments pushed to it) will be returned and then rendered by React.

  • In HighScore.js, you wrote:
// You wrote:
<h3>{score.userName}</h3>

// It should be:
<h3>{score.username}</h3>

// because in highScoreData.js, the property in the objects is named username.

Try making the above changes. If it works, good. If not, post your latest code either in Codebytes or as formatted code ([How to] Format code in posts).

1 Like

Wow… Thanks so much for the time you spent looking at this and writing back. REALLY appreciate it. I made the changes and it seems to work.

1 Like

May I request some help. I must be doing something silly here. I do not seem to see the list of scores.

import React from "react"; const HighScore = ({ scoreData }) => { const list = scoreData.map((score) => { <div> <h1>Name: {score.username}</h1> <h2>Score: {score.score}</h2> <h3>Date: {score.date}</h3> </div> }); return <div>{list}</div>; }; export default HighScore;
import React from "react"; import TitleScreen from "./TitleScreen"; import HighScore from "./HighScore"; import { highScores } from "./highScoreData"; function App() { return ( <> <TitleScreen /> <HighScore scoreData={highScores} /> </> ); } export default App;

In HighScore.js, you are passing an arrow function to the map method.

If you use curly braces for the body of an arrow function, then you need to use the return keyword to do an explicit return. Alternatively, you can omit the curly braces and let the arrow function do an implicit return.

Since, you are using curly braces for the body of the arrow function, you need to do an explicit return.

// You wrote:
const HighScore = ({ scoreData }) => {
  const list = scoreData.map((score) => {
    <div>
      <h1>Name: {score.username}</h1>
      <h2>Score: {score.score}</h2>
      <h3>Date: {score.date}</h3>
    </div>
  });

  return <div>{list}</div>;
};
// If curly braces used for body of arrow function,
// then explicit return is necessary:
const HighScore = ({ scoreData }) => {
  const list = scoreData.map((score) => {
    return <div>               
      <h1>Name: {score.username}</h1>
      <h2>Score: {score.score}</h2>
      <h3>Date: {score.date}</h3>
    </div>
  });

  return <div>{list}</div>;
};
// If curly braces are omitted for body of arrow function,
// then implicit return is sufficient:
const HighScore = ({ scoreData }) => {
  const list = scoreData.map((score) => 
    <div>               
      <h1>Name: {score.username}</h1>
      <h2>Score: {score.score}</h2>
      <h3>Date: {score.date}</h3>
    </div>
  );

  return <div>{list}</div>;
};

Also, since the map method returns an array, so list will be an array.
You don’t need to wrap the array in a div or fragment.

// This will work:
return <div>{list}</div>;

// This will also work:
return list;
// The elements are not being returned separately, but
// as an array, so don't need to wrap the array in a div.
2 Likes

That worked very well! Thanks for the reminder of the basic rules of an arrow function! I appreciate it!

1 Like

My solution:

1 Like

I just want to highlight this as really useful; this was my problem also! Thanks, I was struggling for a while. I even had gone to the inspect console and could understand that my error was in HighScore.js but because of the way the React is compiled for the web, I could not understand further about what my error was.

1 Like