Antoine BERNIER
  • NEW!
    NEW!  Connect Ideas Across Notes
    Save time and share insights. With Paragraph Citation, you can quote others’ work with source info built in. If someone cites your note, you’ll see a card showing where it’s used—bringing notes closer together.
    Got it
      • Create new note
      • Create a note from template
        • Sharing URL Link copied
        • /edit
        • View mode
          • Edit mode
          • View mode
          • Book mode
          • Slide mode
          Edit mode View mode Book mode Slide mode
        • Customize slides
        • Note Permission
        • Read
          • Only me
          • Signed-in users
          • Everyone
          Only me Signed-in users Everyone
        • Write
          • Only me
          • Signed-in users
          • Everyone
          Only me Signed-in users Everyone
        • Engagement control Commenting, Suggest edit, Emoji Reply
      • Invite by email
        Invitee

        This note has no invitees

      • Publish Note

        Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note No publishing access yet

        Your note will be visible on your profile and discoverable by anyone.
        Your note is now live.
        This note is visible on your profile and discoverable online.
        Everyone on the web can find and read all notes of this public team.

        Your account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

        Your team account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

        Explore these features while you wait
        Complete general settings
        Bookmark and like published notes
        Write a few more notes
        Complete general settings
        Write a few more notes
        See published notes
        Unpublish note
        Please check the box to agree to the Community Guidelines.
        View profile
      • Commenting
        Permission
        Disabled Forbidden Owners Signed-in users Everyone
      • Enable
      • Permission
        • Forbidden
        • Owners
        • Signed-in users
        • Everyone
      • Suggest edit
        Permission
        Disabled Forbidden Owners Signed-in users Everyone
      • Enable
      • Permission
        • Forbidden
        • Owners
        • Signed-in users
      • Emoji Reply
      • Enable
      • Versions and GitHub Sync
      • Note settings
      • Note Insights New
      • Engagement control
      • Make a copy
      • Transfer ownership
      • Delete this note
      • Save as template
      • Insert from template
      • Import from
        • Dropbox
        • Google Drive
        • Gist
        • Clipboard
      • Export to
        • Dropbox
        • Google Drive
        • Gist
      • Download
        • Markdown
        • HTML
        • Raw HTML
    Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
    Create Create new note Create a note from template
    Menu
    Options
    Engagement control Make a copy Transfer ownership Delete this note
    Import from
    Dropbox Google Drive Gist Clipboard
    Export to
    Dropbox Google Drive Gist
    Download
    Markdown HTML Raw HTML
    Back
    Sharing URL Link copied
    /edit
    View mode
    • Edit mode
    • View mode
    • Book mode
    • Slide mode
    Edit mode View mode Book mode Slide mode
    Customize slides
    Note Permission
    Read
    Only me
    • Only me
    • Signed-in users
    • Everyone
    Only me Signed-in users Everyone
    Write
    Only me
    • Only me
    • Signed-in users
    • Everyone
    Only me Signed-in users Everyone
    Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note No publishing access yet

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.

    Your account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

    Your team account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

    Explore these features while you wait
    Complete general settings
    Bookmark and like published notes
    Write a few more notes
    Complete general settings
    Write a few more notes
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    --- tags: ironhack, lecture, --- <style> .markdown-body img[src$=".png"] {background-color:transparent;} .alert-info.lecture, .alert-success.lecture, .alert-warning.lecture, .alert-danger.lecture { box-shadow:0 0 0 .5em rgba(64, 96, 85, 0.4); margin-top:20px;margin-bottom:20px; position:relative; ddisplay:none; } .alert-info.lecture:before, .alert-success.lecture:before, .alert-warning.lecture:before, .alert-danger.lecture:before { content:"👨‍🏫\A"; white-space:pre-line; display:block;margin-bottom:.5em; /*position:absolute; right:0; top:0; margin:3px;margin-right:7px;*/ } b { --color:yellow; font-weight:500; background:var(--color); box-shadow:0 0 0 .35em var(--color),0 0 0 .35em; } .skip { opacity:.4; } </style> ![logo_ironhack_blue 7](https://user-images.githubusercontent.com/23629340/40541063-a07a0a8a-601a-11e8-91b5-2f13e4e6b441.png) # React | Components & Props ## Learning Goals * Know how the Component tree works * How the DOM is rendered in the browser * What props are in React components * Syntax for passing props to a component ## Introduction - Know how the Component tree works **Components are the core building block of React apps.** A typical React app is composed of multiple components. That structure can be represented as a **component tree** - having one root component (usually named "App" component) and then a potentially infinite amount of nested child & descendant components. :::info lecture Le découpage d'une application en composants va nous permettre de la simplifier en plus petits morceaux : ![](https://i.imgur.com/zNklNy7.jpg =250x) --- et ainsi de la : - simplifier (un composant fait une chose) - découpler (tout n'est pas lié, chaque composant est plus indépendant) -> cf. [separation of concerns](https://fr.wikipedia.org/wiki/S%C3%A9paration_des_pr%C3%A9occupations) ::: :::info lecture Un composant pourra être : - aussi grand que toute notre application - qu'aussi petit qu'un simple bouton ![](https://i.imgur.com/8I8idJV.png) ::: :::info lecture Un composant contiendra d'autres composants : structure imbriquée [![](https://i.imgur.com/LqUw8YM.png) ](https://mbostock.github.io/d3/talk/20111116/pack-hierarchy.html) ::: :::info lecture React devTools extension nous permettra d'inspecter la structure de nos différents composants : ![](https://i.imgur.com/843i1D6.png) ::: --- React lets you define components as classes or functions. **Functional components** are just JavaScript functions and they let you return/render some jsx to the DOM. They **can receive props** but they **don't have state**. More about this when we talk about **state** in a different lesson. **Components** defined **as classes** currently provide more features. The first and the most important one is that class components can **have state** (again more on that in a later lesson). The most common way to define a React class component is by extending React's built-in `React.Component` class: :::info lecture La première façon que nous verrons de créer un composant sera sous forme d'une classe, étendue de `React.Component` : ::: ```jsx import React from "react"; class Welcome extends React.Component { render() { // return some jsx here } } ``` :::info lecture `React.Component` VS. `{ Component }` : ::: You might also see the `React.Component` class referenced as just `Component` class when it's imported directly from the `react` library: ```jsx import React, { Component } from "react"; class Welcome extends Component { render() { // return some jsx here } } ``` :::info lecture Rappel cheatsheet [ES6 modules](https://www.notion.so/abernier/JS-aa22c24cf2374ef09e7b0841885e2c0d#c0bdf894c8b046e5b54082c443b00edd). ::: Here we create our class `Welcome` by extending React's `Component`. We do this to make our class inherit all the useful built-in properties and methods of a React component. Both of previous examples are the same, just in the second example we are dealing with [named import](https://developer.mozilla.org/pt-PT/docs/Web/JavaScript/Reference/Statements/import). :::warning :warning: <b>Importing `React` from the `react` library is **always** required</b> in every React component (class or function) because it is responsible for rendering our content to the DOM. ::: :::success lecture C'est d'ailleurs comme cela que nous avons créer notre premier composant `<App />`. ::: So far this all looks familiar, right? This is the way our `App.js`, the root component is built. :::info :bulb: Conceptually, components are like JavaScript functions. They accept arbitrary inputs (called `props`) and return React elements describing what should appear on the screen. ::: Let's go now into our code in `react-module-day1-start` and let's make some structural changes. First of all, so far we have only one component (*App.js component*) and we said that React is all about working with a lot of components, so let's update our code. In the root of our app let's create folder `components` and in this folder, let's create `User.js` file. `User.js` is going to be example of a *functional* component. :::info lecture Créons un 2e composant `<User />` dans notre projet `react-module-day1-start` : ::: ```jsx // src/User.js import React from "React"; class User extends React.Component { render() { return ( <div className="User"> <p>Welcome, Pablo!</p> </div> ); } } export default User; ``` :::info lecture - Importons ce composant dans `App` - Créons 2 instances de ce composant `<User/>` dans `<App/>` -> Expliquer les instances et les relier aux classes ::: ## Props :::info lecture Plutôt que de toujours afficher `"Welcome, Pablo!"`, nous allons vouloir passer le prénom en paramètre... ::: One of the fundamental concepts when dealing with React components is that of **props** - these are the _pieces of information that come from outside of the component_. Another way to describe them is they are _the data passed into the component_. The term **props** is short for _properties_. In JSX, when a prop is sent to a component, it looks like an HTML attribute. In our `render` method in `App.js` component, let's find `<User />` tag and let's pass our first prop `firstName` to the `User.js` component. :::info lecture Voici comment nous allons pouvoir "passer des choses" à notre composant lors de son instanciation : ::: ```jsx // src/App.js ... <User firstname="Joe" /> <User firstname="Billy" /> ... ``` :::info lecture NB : montrer que les props sont affichées dans l’onglet React NB : props est un peu comme des paramètres que l’on passe à des fonctions. ::: And after that let's update our `User.js` component: :::info lecture Modifions notre composant afin qu'il tienne compte de ce paramètre `firstname` transmis (`this.props.firstname` L11) : ::: ```jsx= // src/User.js import React from "React"; class User extends React.Component { render() { console.log("props=", this.props); // 👈 return ( <div className="User"> <p>Welcome, {this.props.firstname}!</p> {/* 👈 */} </div> ); } } export default User; ``` :::info lecture - L7: montrer que `this.props` vaut un objet des props passées ::: In a functional component like `User` we receive all the props as the **first argument** of the function. We refer to that variable by its name, `props` and access indivual props from inside the object with dot notation like `{props.firstName}`. :::warning :warning: If we were inside a class we would have to use `this` keyword so it would be `{this.props.firstName}`. ::: If rebundle our app now (`npm run webpack`) we can see the changes. And now if we talk about reusability, we can reuse our `User` component and pass different data to change the way it's displayed. We can display the component again by adding another `<User />`. ```jsx // App.js // ... render() { return ( <div className="App"> <User firstName="Joe"/> <User firstName="Billy"/> </div> ); } // ... ``` Rebundle your app and check out the changes in the DOM. So far we covered **props** and we now know that props allow us to **pass data in the component**. Explained with industry terms, we could say that **props allow you to pass data down the component tree**. Changes in component triggered by props will eventually lead to re-rendering the DOM. :::info lecture Montrer que le changement de la valeur de firstname engendre le re-rendu automatique du composant : ![](https://i.imgur.com/XTYeHhk.png) ::: :::info The changes in `props` and/ or `state` trigger React to re-render the components and potentially update the DOM. ::: --- :::info lecture Bonus -- Let's now reuse our `user` object and pass some extra-props to our first `<User/>`: ```jsx <User firstname={user.firstname} lastname={user.lastname} email={user.emails[0]} photo={user.avatarUrl} /> ``` ```jsx function displayAvatar(avatarUrl) { if (avatarUrl) { return <img src={avatarUrl}/>; } else { return <img src="https://twirpz.files.wordpress.com/2015/06/twitter-avi-gender-balanced-figure.png?w=1280"/>; } } class User extends React.Component { render() { console.log(this.props); const {firstname, lastname, email, photo} = this.props; return ( <div className="User"> <p>Welcome, {firstname} {lastname}!</p> Your email is {email} and your photo is {displayAvatar(photo)}; </div> ); } } ``` ::: ## When do you use props? ### (1) Props are like function arguments :::info lecture Les props se comportent un peu comme des paramètres d'une fonction, mais cette fois appliqués à un composant. ::: You can use props to make your components re-usable. Props usually control how a component is displayed so passing in **different props** often results in the component **looking or behaving differently**. In this way, props for a component are like arguments of a function. Arguments control how a function behaves just like props control how a component is displayed. ![](https://s3-eu-west-1.amazonaws.com/ih-materials/uploads/upload_53610b5ab842828224a29e2fb18fe4dc.png) Imagine we had a cool **component to display the weather** of a particular city. In that case the prop we send would probably be the city name. Using that name it would probably access the weather data from an API. Rendering the component would probably look like this: ```jsx // This code is just hypothetical // ... render() { return <WeatherWidget city="Mexico City" />; } // ... ``` Sending a different `city` prop should produce different information. ![](https://s3-eu-west-1.amazonaws.com/ih-materials/uploads/upload_994ae09ba982413b0341b87a94fe6610.png) ### (2) Share data between components :::info lecture Les props sont donc une façon de communiquer une données à un composant. Ce composant peut alors lui-même, repasser cette même info à un autre composant et faire descendre l'information... ::: By definition, props let you **share data** between a parent component and a child component. Sharing data is important because you will eventually have many components inside your application and it's quite common for an action that happens in one component **to affect how another** should behave. The `App` component can share information with its child `User` and `User` can also share information with its potential children and so forth. ![](https://s3-eu-west-1.amazonaws.com/ih-materials/uploads/upload_ca57ec2aeceab7798d6c5d0013d58061.png) ### (3) Components from npm There are many pre-made components on npm. Often, components you get from npm will allow you to configure and customize them through the use of props. Let's see an example! First let's install the `react-player` npm package. :::info lecture Beaucoup de librairies existent sous forme de composants React, comme `<ReactPlayer>` : ::: ```shell $ npm install react-player ``` Now let's import it inside `App.js`: ```jsx // App.js import React, { Component } from "react"; // import the npm package's component import ReactPlayer from "react-player"; import "./App.css"; // ... ``` Next, we use it in our JSX. The basic usage only involves the `url` prop – the address of the video we want to display. It works with many of the popular video services like YouTube and Vimeo. Let's start with a popular Vimeo video. :::info lecture Instancions `<ReactPlayer />` ::: ```jsx // App.js // ... render() { return ( <div className="App"> <User firstName="Harper"/> <User firstName="Ana"/> // our Vimeo video <ReactPlayer url="https://vimeo.com/channels/top/22439234" /> </div> ); } // ... ``` Aside from `url` the component also has other props which you can find in [the package's documentation](https://github.com/CookPete/react-player#readme). Let's try some of the other ones with a YouTube video. First there's the `playing` prop – a boolean prop that controls autoplay. :::info lecture Essayons la prop `playing` vue dans la doc : ::: ```jsx // App.js // ... render() { return ( <div className="App"> <User firstName="Harper"/> <User firstName="Ana"/> <ReactPlayer url="https://vimeo.com/channels/top/22439234" /> // our YouTube video <ReactPlayer url="https://www.youtube.com/watch?v=kJQP7kiw5Fk" playing /> </div> ); } // ... ``` Don't like the most popular YouTube video of the day? Maybe two new props can help! The `controls` prop adds player controls and the `volume` prop lets you control the volume. :::info lecture ou encore `controls` ou `volume=""` ::: ```jsx // App.js // ... render() { return ( <div className="App"> <User firstName="Harper"/> <User firstName="Ana"/> <ReactPlayer url="https://vimeo.com/channels/top/22439234" /> // see the new props! <ReactPlayer url="https://www.youtube.com/watch?v=kJQP7kiw5Fk" playing controls volume="0.5" /> </div> ); } // ... ``` In a mature component like `ReactPlayer`, you can see that props allow you to customize the way the component works for you. ## Summary In this lesson we covered the core of the React magic world - we learned about components and influencing them from the outside using *props*. Props are like function arguments but for components and they let you share data between components. Also components from npm use props a lot for customization and configuration. ## Extra Resources - [`React.Component` on reactjs.org](https://reactjs.org/docs/react-component.html) - [Understanding Props in React](https://www.agiliq.com/blog/2018/05/understanding-react-state-and-props/#understanding-reactjs-props)

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password
    or
    Sign in via Google Sign in via Facebook Sign in via X(Twitter) Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    By signing in, you agree to our terms of service.

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully