Sauter au contenu

Cours 02 - Le routeur et les composantes

Le nom des fichiers ainsi que la structure des dossiers à l’intérieur du dossier app sont étroitement liés à la navigation à l’intérieur de l’application.

Le fichier app/page.jsx permet d’afficher la page d’accueil (/).

Pour chaque segment d’url devant correspondre à une page (pour afficher du UI), un fichier page.js ou page.jsx doit être utilisé.

Tous les sous-dossiers du dossier app correspondent à un segment de l’url. Par exemple, le fichier /app/projets/page.jsx s’afficherait à l’url /projets et /app/users/me/page.jsx à l’url /users/me.

  • Répertoireapp/
    • page.jsx page d’accueil (/)
    • Répertoirea-propos
      • page.jsx correspond à l’url /a-propos
    • Répertoireblog/
      • page.jsx correspond à l’url /blog
      • Répertoireposts/
        • Répertoirenouveau/
          • page.jsx correspond à l’url /blog/posts/nouveau
    • Répertoireprojets/
      • page.jsx correspond à l’url /projets
    • Répertoireusers/
      • Répertoireme/
        • page.jsx correspond à l’url /users/me

Noms de fichiers spéciaux du App Router (1ère partie)

Section intitulée « Noms de fichiers spéciaux du App Router (1ère partie) »

page.jsx

Composante affichée à l’url correspondant aux dossier contenant le fichier.

layout.jsx

Composante affichant la portion statique de l’interface (affiché autour de page.jsx en utilisant le props children). Les layouts peuvent être imbriqués par cascade

not-found.jsx

Composante affichée lorsqu’un url ne correspond à aucune page existante. La composante affichée sera la première trouvé dans la hiérarchie en remontant les segments vers la racine.

Une composante fonctionnelle est une fonction devant retourner du JSX (syntaxe ressemblant à du html, mais c’est du JS!).

function UneComposante(props) {
return (
<div>
<h1>Du contenu</h1>
</div>
);
}
// ou
const UneComposante = (props) => {
return (
<div>
<h1>Du contenu</h1>
</div>
);
};
// ou (comme la fonction ne fait rien d'autre que de retourner du jsx)
const UneComposante = (props) => (
<div>
<h1>Du contenu</h1>
</div>
);

On peut ensuite utiliser UneComposante à l’intérieur d’une composante parent depuis le même fichier jsx.

const App = (props) => (
<div>
<UneComposante />
</div>
);
//App est exporté pour être utilisé depuis un autre fichier
export default App;

Étant donné que le JSX est une extension du JS (plutôt que du HTML), certaines règles s’appliquent lors de sa rédaction:

Un seul élément racine

Le JSX d’une composante doit être enrobé d’un seul élément. En cas de nécessité (CSS ou autre), un fragment peut être utilisé.

Balises fermées

Toutes les balises doivent être fermées. La flexibilité introduite dans html5 ne s’applique pas au JSX. On utilise des balises auto-fermantes pour les éléments vide et des balise fermantes pour les éléments avec contenu.

Des attributs différents

Comme certains mots comme class ou for sont des mots réservés en Javascript, certains attributs ont été renommés. Par exemple, on utilise className plutôt que class et htmlFor plutôt que for.

Tous les attributs à mots composés contenants des tirets sont renommés en camelCase. Par exemple, stroke-width devient strokeWidth.

En développement, la compilation demeure davantage permissive. Votre console indiquera si certains attributs doivent être renommés.

L’extension VSCode Class-to-classname permet également de renommer tous les attributs class lors d’un copier-coller.

Il est aussi possible de passer des données dynamiquement à UneComposante en ajoutant des attributs au nom arbitraire qui pourront être récupérées à l’intérieur des props de UneComposante.

On peut afficher dynamiquement des données ou exécuter des commandes js simples à l’aide des moustaches.

const App = (props) => (
<div>
  {/* On crée un nouvel attribut titre */}
  <UneComposante titre="Le titre de cette composante" />
</div>
);

const UneComposante = (props) => (
<div>
  {/* ce qui a été passé en attribut est récupéré dans l'objet props */}
  <h1>{props.titre}</h1>
  <h2 style={{color: 'cornflowerblue'}}>{props.titre.split(" ")[4]}</h2>
</div>
);

export default App;

On peut passer du texte statique à une composantes à travers ses props, mais on peut également passer tout type de contenu ainsi que des variables en utilisant les moustaches:

const App = (props) => {
const texte = "du texte";
const nombre = 5;
return (
<main>
<UneComposante titre={texte} age={10} nombre={nombre} objet={{prop1: 2, prop2: "texte"}} />
</main>
);
};
export default App;#

Pour faire un suivi plus facile et améliorer la complétion de code par l’IDE pour les props passées à une composante, on utilisera la décomposition d’objet:

// en utilisant les accolades,
// on ne récupère que les propriétés identifiées plutôt que l'objet lui-même
const UneComposante = ({titre, age, nombre, objet}) => (
<div>
<h1>{titre}: {objet.prop1}</h1>
</div>
)

On réserve normalement le style global de l’application (reset, variables CSS globales, TailwindCSS) dans le fichier global.css.

Pour le style propre à une composante, on crée normalement un fichiers CSS dédié qui porte le même nom que la composante:

  • Répertoiresrc/
    • Répertoireapp/
      • Répertoire_components/
        • Button.jsx
        • Button.css
        • Card.jsx
        • Card.css

On y déclarera le nom d’une classe du même nom que la composante.

Button.css
.Button {
padding: 12px 24px;
border-radius: 6px;
border: none;
cursor: pointer;
}

Cette classe pourra ensuite être appliquée sur l’élément approprié dans le fichier .jsx:

Button.jsx
const Button = () => {
return (
<button className="Button">Clic</Button>
);
};

Afin que le fichier CSS soit inclus dans le projet, il doit être importé par un autre fichier. On procède donc normalement à l’importation depuis le fichier de la composante:

Button.jsx
import './Button.css';
const Button = () => {
return (
<button className="Button">Clic</Button>
);
};

Le dossier public (à la racine du projet) permet de stocker les fichiers statiques directement accessibles par leur url.

Tous les fichiers statiques déposés dans le dossier public peuvent être liés dans le code et sont accessibles par l’url de base (/).

Ainsi:

  • Répertoirepublic/
    • icon.png acessible par l’url “/icon.png”
    • Répertoireimg/
      • photo.png accessible par l’url “/img/photo.png”
  • Répertoiresrc/
<div>
<img src="/icon.png" alt="Icône à afficher"/>
<img src="/img/photo.png" alt="Photo qui évoque des choses"/>
</div>