Cómo construí la aplicación meteorológica en freeCodeCamp usando React y Typescript

Así que finalmente decidí volver a freeCodeCamp y tratar de terminar mi Certificado de Desarrollo de Front End. Ya había terminado todos los algoritmos y tutoriales a principios del año pasado, y lo único que faltaba eran los proyectos.

Pero ahora que tengo más experiencia como Full Stack Developer, la mayoría de los proyectos son un poco fáciles para mi nivel actual. Entonces tenía dos opciones. Podría volver a lo básico y terminarlos todos en un día, o podría matar dos pájaros de un tiro: divertirme y experimentar con la tecnología mientras trabajo en estos proyectos. Opté por lo último.

Pero hagamos esos tres pájaros, porque he querido escribir un tutorial / guía durante un tiempo. Hoy, lo que vamos a abordar es el proyecto Show The Local Weather. ¡Pero esta vez, combinará React y Typecript! Puede ver el código terminado en este repositorio de GitHub, así como una demostración en vivo aquí.

Antecedentes

Así que lo primero es lo primero: ¿por qué querría hacer esto? Bueno, aquí está la cosa: he estado saltando de un lado a otro con Angular 5 y React por un tiempo. Y me gusta más React como marco. Es pequeño y conciso, pero tiene todas las características que necesita para crear una aplicación de página única completamente funcional. En cuanto a Angular, es demasiado grande para disfrutarlo en una aplicación tan pequeña como esta ... ¡pero usa Typecript!

TypeScript es un superconjunto de JavaScript que agrega muchas características que simplemente faltan en JavaScript, incluso con las mejoras de ES6 / 7. Es principalmente conocido por su escritura estática. Entonces me pregunté si podría obtener lo mejor de ambos mundos. La respuesta fue un rotundo SI!… Redux no incluido. (Quiero decir que puedes incluir Redux, pero hasta ahora ha sido un dolor de cabeza configurarlo, así que no lo haré para esta guía).

Para este proyecto, nos centraremos en lo mínimo de las Historias de usuarios, porque mi enfoque es la tecnología en lugar de las características adicionales. Como tal, la API que usaremos para esta aplicación será Wunderround. Es perfecto para lo que estamos construyendo, porque ofrecen temperaturas en Fahrenheit y Celsius y también proporcionan iconos para las diferentes condiciones climáticas. Esto significa menos trabajo programático por nuestra parte.

Paso 0: configurar

Usaré create-react-apppara este proyecto, con el script React personalizado para Typecript, para que podamos mantener la configuración cero y la facilidad de uso. Trey Huffine escribió un buen artículo sobre cómo configurar una aplicación React con TypeScript y se puede encontrar aquí.

Definitivamente sugiero mirar esa publicación para una configuración más profunda. Pero sin más preámbulos, vamos a ejecutar la siguiente línea en la terminal.

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

Llegaré a los decoradores un poco más tarde. Solo sé que es una pequeña característica interesante que estaba realmente emocionado de probar. Pero para poder usarlo, tendremos que editar nuestro tsconfig.jsonarchivo para incluir decoradores experimentales. Para hacer esto, simplemente agregue la línea de código en negrita.

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

Y como tengo Prettier instalado en mi entorno de desarrollo, tuve que cambiar mi tslint.jsonarchivo porque el lint entró en conflicto con el formateador. Si tiene una configuración de desarrollo similar, sugiero que elimine todas las reglas de tslint para que no tenga que atascarse en la configuración. El archivo debería verse así después de que hayas terminado.

La estructura de carpetas que utilizaré será similar a la siguiente. Puede crear, eliminar y mover archivos en consecuencia.

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

Está bien, ¡lo peor ya pasó! Finalmente hemos configurado nuestra aplicación. Vamos a sumergirnos en el código.

Paso 1: estilo

Primero quiero quitar el estilo del camino. No soy un gran diseñador, así que todo lo que hice fue cambiar la piel de los create-react-appestilos predeterminados para que tuvieran el tema verde freeCodeCamp. Además, hice que el botón fuera más parecido a un botón y, por supuesto, más verde. Usted es libre de volverse loco con esto si resulta que es un maestro de CSS. También puede descargar archivos de imagen aquí y colocarlos en su assets/carpeta.

Paso 2: Está bien, mentí… Más configuración

Pero no se preocupe, esta vez es código real. Primero comencemos con la parte fácil: agregar su API y sus claves API. No hay nada nuevo aquí: se ve exactamente como JavaScript normal hasta ahora.

Ahora, para lo específico de TypeScript, tenemos que especificar tipos. Bueno, no tenemos que hacerlo, pero definitivamente deberíamos. La razón detrás de la escritura estática es que nos brinda seguridad. A diferencia de JavaScript normal, nuestro código no se ejecutará si las cosas son del tipo incorrecto. Básicamente, esto significa que el compilador simplemente no nos permitirá escribir código incorrecto.

Como puede ver, no da demasiado miedo. Simplemente agregue el tipo después de dos puntos. Los tipos primitivos (cadena, número, booleano) se admiten fuera de la puerta. Con los objetos, es una buena idea crear un nuevo tipo específico para ese objeto en particular como se ve WeatherDatacon DisplayLocation.

Ahora, era un poco vago, porque la forma de los datos que provienen de nuestra API es mucho más grande y podría haber creado el objeto completo. Pero opté por tomar lo que necesitaba y descartar el resto, razón por la cual este types.tsarchivo es tan pequeño como es.

Paso 3: Reaccionar - La parte divertida

Voy a omitir los archivos index.tsxy App.tsxporque realmente no hay nada realmente nuevo allí. Solo sepa que las importaciones son diferentes debido a lo estricto que es TypeScript con los módulos. En cambio, vamos a repasar primero el componente de presentación.

Sigo prefiriendo desestructurar Componenty Fragmentdesde React, en lugar de llamar React.Component, ya que reduce la redundancia. Y para los fragmentos, si nunca antes ha jugado con ellos, es básicamente un div que no aparece en el marcado HTML.

También notará que he agregado interfaces en la parte superior. Una interfaz especifica cómo deberían verse nuestros accesorios y nuestro estado. Y si no lo ha notado, el truco de TypeScript es agregar tipos a todo, así que eso es lo que está sucediendo arriba dentro de los corchetes angulareste>. 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.