Comment j'ai construit l'application météo dans freeCodeCamp en utilisant React et Typescript

J'ai donc finalement décidé de revenir sur freeCodeCamp et d'essayer de terminer mon certificat de développement Front End. J'avais déjà terminé tous les algorithmes et tutoriels plus tôt l'année dernière, et la seule chose qui manquait était les projets.

Mais maintenant que j'ai plus d'expérience en tant que développeur Full Stack, la plupart des projets sont un peu faciles pour mon niveau actuel. J'avais donc deux choix. Je pourrais soit revenir aux bases et les terminer tous en une journée, soit faire d'une pierre deux coups: m'amuser et expérimenter la technologie tout en travaillant sur ces projets. J'ai opté pour ce dernier.

Mais faisons que trois oiseaux - parce que je voulais écrire un tutoriel / guide depuis un moment. Aujourd'hui, nous allons nous attaquer au projet Show The Local Weather. Mais cette fois, ça va combiner React et Typescript! Vous pouvez consulter le code fini dans ce dépôt GitHub, ainsi qu'une démo en direct ici.

Contexte

Alors la première chose est la première: pourquoi voudrais-je faire ça? Eh bien, voici la chose: je fais des allers-retours avec Angular 5 et React depuis un moment maintenant. Et j'aime plus React en tant que framework. Il est petit et concis, mais possède toutes les fonctionnalités dont vous avez besoin pour créer une application à page unique entièrement fonctionnelle. Quant à Angular, il est beaucoup trop grand pour que je puisse en profiter pour une application aussi petite que celle-ci… mais elle utilise Typescript!

TypeScript est un super ensemble de JavaScript qui ajoute de nombreuses fonctionnalités qui manquent juste à JavaScript, même avec les améliorations d'ES6 / 7. Il est surtout connu pour son typage statique. Je me suis donc demandé si je pouvais tirer le meilleur parti des deux mondes. La réponse a été un OUI retentissant!… Redux non inclus. (Je veux dire que vous pouvez inclure Redux, mais jusqu'à présent, la configuration a été difficile, je ne le ferai donc pas pour ce guide.)

Pour ce projet, nous allons nous concentrer sur le strict minimum des User Stories, car je me concentre sur la technologie plutôt que sur les fonctionnalités supplémentaires. En tant que tel, l'API que nous utiliserons pour cette application sera Wunderround. C'est parfait pour ce que nous construisons, car ils offrent des températures en degrés Fahrenheit et Celsius et fournissent également des icônes pour les différentes conditions météorologiques. Cela signifie moins de travail programmatique de notre côté.

Étape 0: configuration

Je vais utiliser create-react-apppour ce projet, avec le script React personnalisé pour Typescript, afin que nous puissions conserver la configuration zéro et la facilité d'utilisation. Un bon article sur la configuration d'une application React avec TypeScript a été écrit par Trey Huffine et peut être trouvé ici.

Je suggère vraiment de regarder ce post pour une configuration plus approfondie. Mais sans plus tarder, nous allons lancer la ligne suivante dans le terminal.

create-react-app weather --scripts-version=react-scripts-tsnpm install --save core-decorators

Je reviendrai aux décorateurs un peu plus tard. Sachez simplement que c'est une petite fonctionnalité intéressante que j'ai vraiment hâte d'essayer. Mais pour pouvoir l'utiliser, nous devrons éditer notre tsconfig.jsonfichier pour inclure des décorateurs expérimentaux. Pour ce faire, ajoutez simplement la ligne de code en gras.

{ "compilerOptions": {// ...code hidden... "noUnusedLocals": true, "experimentalDecorators": true } // ...more code hidden...}

Et depuis que j'ai installé Prettier sur mon environnement de développement, j'ai dû changer mon tslint.jsonfichier car la charpie était en conflit avec le formateur. Si vous avez une configuration de développement similaire, je suggère simplement de supprimer toutes les règles tslint afin que vous n'ayez pas à vous enliser dans la configuration. Le fichier devrait ressembler à ceci une fois que vous avez terminé.

La structure de dossiers que j'utiliserai ressemblera à ce qui suit. Vous pouvez créer, supprimer et déplacer des fichiers en conséquence.

weather-app/├─ .gitignore├─ node_modules/├─ public/├─ src/ └─ assets/ | - - loader.svg | - - logo.svg └─ components/ | - - Weather.tsx | - - WeatherDisplay.tsx └─ styles/ | - - App.css | - - WeatherDisplay.css | — — index.tsx | — — registerServiceWorker.ts | — — App.tsx | — — index.css | - - config.ts | - - types.ts├─ package.json├─ tsconfig.json├─ tsconfig.test.json└─ tslint.json

D'accord, le pire est passé! Nous avons enfin mis en place notre application. Plongeons dans le code.

Étape 1: Styling

Je veux d'abord éliminer le style. Je ne suis pas vraiment un concepteur, donc tout ce que j'ai vraiment fait a été de redessiner les create-react-appstyles par défaut pour avoir le thème vert freeCodeCamp. De plus, j'ai rendu le bouton plus semblable à un bouton et, bien sûr, plus vert. Vous êtes libre de vous déchaîner avec cela si vous êtes un maître CSS. Vous pouvez également télécharger des fichiers image ici et les placer dans votre assets/dossier.

Étape 2: D'accord, j'ai menti… Plus de configuration

Mais ne vous inquiétez pas, c'est du code réel cette fois. Commençons par la partie la plus simple: ajouter vos clés API et API. Rien de nouveau ici - il ressemble exactement au JavaScript normal jusqu'à présent.

Maintenant, pour la chose spécifique à TypeScript, nous devons spécifier des types. Eh bien, nous n'avons pas à le faire, mais nous devrions certainement le faire. La raison derrière le typage statique est qu'il nous donne la sécurité. Contrairement au JavaScript normal, notre code ne fonctionnera pas si les éléments sont du mauvais type. Cela signifie essentiellement que le compilateur ne nous laissera pas écrire du mauvais code.

Comme vous pouvez le voir, ce n'est pas trop effrayant. Ajoutez simplement le type après un deux-points. Les types primitifs (chaîne, nombre, booléen) sont pris en charge hors de la porte. Avec les objets, c'est une bonne idée de créer un nouveau type spécifique à cet objet particulier comme vu dans WeatherDataavec DisplayLocation.

Maintenant, j'étais un peu paresseux, car la forme des données provenant de notre API est beaucoup plus grande, et j'aurais pu créer tout l'objet. Mais j'ai choisi de prendre simplement ce dont j'avais besoin et de supprimer le reste, c'est pourquoi ce types.tsfichier est aussi petit qu'il est.

Étape 3: Réagissez - La partie amusante

Je vais sauter les fichiers index.tsxet App.tsxcar il n'y a vraiment rien de vraiment nouveau. Sachez simplement que les importations sont différentes en raison de la rigueur de TypeScript concernant les modules. Au lieu de cela, nous allons d'abord passer en revue la composante de présentation.

Je préfère toujours déstructurer Componentet Fragmentdepuis React, au lieu d'appeler React.Component, car cela réduit la redondance. Et pour les fragments, si vous n'avez jamais joué avec eux auparavant, c'est essentiellement un div qui n'apparaît pas dans le balisage HTML.

Vous remarquerez également que j'ai ajouté des interfaces en haut. Une interface spécifie à quoi devraient ressembler nos accessoires et notre état. Et si vous ne l'avez pas remarqué, le gadget de TypeScript ajoute des types à tout, c'est donc ce qui se passe ci-dessus dans les crochets angulaireste>. If you are familiar with prop types, it does the same thing, but I feel like this is much cleaner.

The next thing is the weird @ symbol. Well, that’s a decorator! I originally wanted to hook up Redux and connect so that I can show a much more complicated version, but the autobind will do for now.

A decorator is basically a function that wraps around the class and applies necessary attributes. It also allows us to use export default at the top, which is just a personal preference of mine.

@decorateexport default Class {}
// is the same as
export default decorate(Class)

In this case autobind will, as the name entails, automatically bind this to everything so we don’t have to worry about binding issues. And coming from a more Object Oriented language, these class methods will look a lot cleaner than the JavaScript work-around with the arrow functions.

classMethod = () => { console.log('when you use arrows, you don't have to worry about the keyword "this"');}
classMethod () { console.log('because of javascript, you have to worry about the keyword "this" here');}

And now finally we move to the bulk of our logic, which is going to be living in the Weather.tsx component.

The first thing you’ll notice is the ? in the interface. I mentioned that we definitely should define types for our props, but what happens when you know for certain it won’t be defined until after the API call? Well we can define optional types with a question mark.

What is happening in the background is that the variable weatherData is only allowed to be a WeatherData type or undefined. Also, remember that our WeatherData type is only a subsection of what wunderground offers. Earlier I mentioned that we are only going to take the data that we needed from the API — well, that’s what that huge destructuring on line 55 is doing.

Did I mention you can specify expected return types of functions? That’s what is happening here with getCurrentPosition , because I wanted to make sure that it returns a promise.

The reasoning here is that I didn’t want to call getCurrentWeather until after we had the correct geolocation, which means we’re dealing with asynchronous events. Async always means Promises, so that’s what’s going to happen.

A word of warning: the native geolocation API does take a long time to get a result without passing in any options. I opted to not add options to it as it was giving me errors at the time.

And I believe that is all the new things happening in this app because of TypeScript. Everything else should be familiar if you know React. But hopefully you can see the benefits of this superset, as it adds both security to our code as well as some nice super powers.

Step 4: Complete!

Original text


You did it! You finished an app that shows the weather at your current position. And in doing so, you’ve covered a good chunk of TypeScript as well as incorporating it into React.

Of course, there can definitely be improvements on this, like an option to search and show other locations. And the UI can definitely be worked on. But if you haven’t already finished the weather app on freeCodeCamp, you have already gone above and beyond on this assignment.