FAQ: Stateless Functional Components - Stateless Functional Components and Props

This community-built FAQ covers the “Stateless Functional Components and Props” exercise from the lesson “Stateless Functional Components”.

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

Web Development

Learn ReactJS: Part II

FAQs on the exercise Stateless Functional Components and Props

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

Ask or answer a question about this exercise by clicking reply (reply) below!

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

Need broader help or resources? Head here.

Looking for motivation to keep learning? Join our wider discussions.

Learn more about how to use this guide.

Found a bug? Report it!

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!

I wonder why implicit return isn’t used in the exercise’s example. The return and semicolon can be dropped, right?

2 Likes

Why did we not use the “function” keyword in the first exercise for creating a stateless function component? Is it something react specific or does javascript not really require you to use that keyword while making stateless functions like those?

There are a few ways you can make a function in JavaScript. You can easily destructure it without having using the “function” keyword.

  1. Function Declarations
  2. Function Expressions
  3. Arrow Function which is known as Big Fat Arrow
  4. Concise Body Arrow Function

Extra info here.

So with this exercise I initially didn’t pass as I was following the example code with how to write the props:

export function YesNoQuestion (props) {
  return (
    <div>
      <p>{props.prompt}</p> // <---- Just {props.prompt}
      <input value="Yes" />
      <input value="No" />
    </div>
  );
}

ReactDOM.render(
  <YesNoQuestion prompt="Have you eaten an apple today?" />,
  document.getElementById('app');
);

Whereas the exercise requires it to be src={props.src}:

export const NewFriend = (props) => {
  		return (
      <div>
        <img src={props.src}/> // <--- Includes src={}
      </div>
    );
}

ReactDOM.render(
  <NewFriend src="https://content.codecademy.com/courses/React/react_photo-squid.jpg" />,
  document.getElementById('app')
);

I was wondering what the difference is?

In React, User-Defined Components must be capitalized.
In the snippets you posted, YesNoQuestion and NewFriend are user-defined components and are capitalized as specified.

Elements such as <img> and <p> etc. are HTML elements and not React components (notice that the tags for these elements are not capitalized).

If we leave aside React for the time being and talk about HTML, then in normal HTML

<p>{props.prompt}</p>

will be displayed on the screen as scrn1

If we wanted to display the string "Have you eaten an apple today?" as the text of a <p> element, then we could write it as:

<p>Have you eaten an apple today?</p>

which will be displayed on screen as scrn2

In React, if we wanted to display the above, we could write it as

return (
    <div>
        <p>Have you eaten an apple today?</p>
        ...

But if we wanted to display a different text, we would have to manually edit the <p> element. In React, the use of curly braces {} allows us to write JavaScript expressions within the curly braces. During compilation, the expression will be evaluated and its value will be used.
This is what is happening in the first snippet you posted.

return (
    <div>
        <p>{props.prompt}</p>
        ...
}

ReactDOM.render(
  <YesNoQuestion prompt="Have you eaten an apple today?" />,
  document.getElementById('app');
);

When an instance of the YesNoQuestion component is being rendered, a string is being provided as the value for the prompt attribute. The attributes and values assigned to these attributes are passed as key-value pairs in a props object.

Because of the curly braces in <p>{props.prompt}</p>, the props.prompt part will be treated as a JavaScript expression. This expression evaluates to the string "Have you eaten an apple today?" and it will be equivalent to <p>Have you eaten an apple today?</p>. The text between the paragraph tags will be displayed on screen.

If we want to change the prompt, we don’t have to edit the YesNoQuestion component i.e. we don’t have to edit anything in

return (
    <div>
        <p>{props.prompt}</p>
        ...

All that we need to edit is the value that we are providing to the instance i.e. we need to edit:

ReactDOM.render(
  <YesNoQuestion prompt="Do you feel happy?" />,
  document.getElementById('app');
);

So, we don’t need to change the component. Just pass a different value to the prompt attribute of the instance.



In the second snippet you posted, the NewFriend component has an HTML <img/> element (as opposed to a <p> element).

Documentation for HTML <img>:

The src attribute is required, and contains the path to the image you want to embed.

src is an attribute of an <img> element.

In the first snippet, the choice of prompt as an attribute name was our choice. We could have used a different attribute name e.g. someText as an attribute name (as long as the expected and provided names match)

return (
    <div>
        <p>{props.someText}</p>
        ...
}

ReactDOM.render(
  <YesNoQuestion someText="Have you eaten an apple today?" />,
  document.getElementById('app');
);

But in the second snippet, src is an attribute of an <img> element and we must provide a value for this attribute. Suppose the image is located at "/media/myPicture.png", we could write the NewFriend component as

return (
      <div>
        <img src="/media/myPicture.png"/>
      </div>
    );

But if we wanted to use a different path or image, then we would have to manually edit the component. Instead we can use curly braces <img src={props.src}/> and then when creating an instance of the NewFriend component, we can use a different value for the src attribute i.e.

ReactDOM.render(
  <NewFriend src="/media/flower.png" />,
  document.getElementById('app')
);

So, the component won’t need to be edited. We would just provide a different value to the instance.

If we wanted, we could use an attribute name of our choice i.e.

export const NewFriend = (props) => {
  		return (
      <div>
        <img src={props.somePath}/>
      </div>
    );
}

ReactDOM.render(
  <NewFriend somePath="/media/flower.png" />,
  document.getElementById('app')
);

Instead of src, we could use a name of our choice e.g. somePath as the attribute. BUT, in the img element the src attribute is required and we can’t use an attribute name of our choice in lieu of it.

<img src={props.somePath}/>   <----- VALID
<img source={props.somePath}/>   <---- INVALID

Thank you! Gosh sometimes I am so laser focussed on that particular syntax that I forget to look around and see the context in which it’s placed! Totally makes sense now!

1 Like