One place for hosting & domains

      How To Develop Applications on Kubernetes with Okteto


      The author selected Girls Who Code to receive a donation as part of the Write for DOnations program.

      Introduction

      The Okteto CLI is an open-source project that provides a local development experience for applications running on Kubernetes. With it you can write your code on your local IDE and as soon as you save a file, the changes can be pushed to your Kubernetes cluster and your app will immediately update. This whole process happens without the need to build Docker images or apply Kubernetes manifests, which can take considerable time.

      In this tutorial, you’ll use Okteto to improve your productivity when developing a Kubernetes-native application. First, you’ll create a Kubernetes cluster and use it to run a standard “Hello World” application. Then you’ll use Okteto to develop and automatically update your application without having to install anything locally.

      Prerequisites

      Before you begin this tutorial, you’ll need the following:

      Step 1 — Creating the Hello World Application

      The “Hello World” program is a time-honored tradition in web development. In this case, it is a simple web service that responds “Hello World” to every request. Now that you’ve created your Kubernetes cluster, let’s create a “Hello World” app in Golang and the manifests that you’ll use to deploy it on Kubernetes.

      First change to your home directory:

      Now make a new directory called hello_world and move inside it:

      • mkdir hello_world
      • cd hello_world

      Create and open a new file under the name main.go with your favorite IDE or text editor:

      main.go will be a Golang web server that returns the message Hello world!. So, let’s use the following code:

      main.go

      package main
      
      import (
          "fmt"
          "net/http"
      )
      
      func main() {
          fmt.Println("Starting hello-world server...")
          http.HandleFunc("/", helloServer)
          if err := http.ListenAndServe(":8080", nil); err != nil {
              panic(err)
          }
      }
      
      func helloServer(w http.ResponseWriter, r *http.Request) {
          fmt.Fprint(w, "Hello world!")
      }
      

      The code in main.go does the following:

      • The first statement in a Go source file must be the package name. Executable commands must always use package main.
      • The import section indicates which packages the code depends on. In this case it uses fmt for string manipulation, and net/http for the HTTP server.
      • The main function is the entry point to your binary. The http.HandleFunc method is used to configure the server to call the helloServer function when a request to the / path is received. http.ListenAndServe starts an HTTP server that listens on all network interfaces on port 8080.
      • The helloServer function contains the logic of your request handler. In this case, it will write Hello world! as the response to the request.

      You need to create a Docker image and push it to your Docker registry so that Kubernetes can pull it and then run the application.

      Open a new file under the name Dockerfile with your favorite IDE or text editor:

      The Dockerfile will contain the commands required to build your application’s Docker container. Let’s use the following code:

      Dockerfile

      FROM golang:alpine as builder
      RUN apk --update --no-cache add bash
      WORKDIR /app
      ADD . .
      RUN go build -o app
      
      FROM alpine as prod
      WORKDIR /app
      COPY --from=builder /app/app /app/app
      EXPOSE 8080
      CMD ["./app"]
      

      The Dockerfile contains two stages, builder and prod:

      • The builder stage contains the Go build tools. It’s responsible for copying the files and building the Go binary.
      • The prod stage is the final image. It will contain only a stripped down OS and the application binary.

      This is a good practice to follow. It makes your production containers smaller and safer since they only contain your application and exactly what is needed to run it.

      Build the container image (replace your_DockerHub_username with your Docker Hub username):

      • docker build -t your_DockerHub_username/hello-world:latest

      Now push it to Docker Hub:

      • docker push your_DockerHub_username/hello-world:latest

      Next, create a new folder for the Kubernetes manifests:

      When you use a Kubernetes manifest, you tell Kubernetes how you want your application to run. This time, you’ll create a deployment object. So, create a new file deployment.yaml with your favorite IDE or text editor:

      The following content describes a Kubernetes deployment object that runs the okteto/hello-world:latest Docker image. Add this content to your new file, but in your case replace okteto listed after the image label with your_DockerHub_username:

      ~/hello_world/k8s/deployment.yaml

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: hello-world
      spec:
        selector:
          matchLabels:
            app: hello-world
        replicas: 1
        template:
          metadata:
            labels:
              app: hello-world
          spec:
            containers:
            - name: hello-world
              image: your_DockerHub_username/hello-world:latest
              ports:
              - containerPort: 8080
      

      The deployment manifest has three main sections:

      • metadata defines the name for your deployment.
      • replicas defines how many copies of it you want running.
      • template tells Kubernetes what to deploy, and what labels to add. In this case, a single container, with the okteto/hello-world:latest image, listening on port 8080, and with the app: hello-world label. Note that this label is the same used in the selector section.

      You’ll now need a way to access your application. You can expose an application on Kubernetes by creating a service object. Let’s continue using manifests to do that. Create a new file called service.yaml with your favorite IDE or text editor:

      The following content describes a service that exposes the hello-world deployment object, which under the hood will use a DigitalOcean Load Balancer:

      k8s/service.yaml

      apiVersion: v1
      kind: Service
      metadata:
        name: hello-world
      spec:
        type: LoadBalancer
        ports:
          - protocol: TCP
            port: 80
            targetPort: 8080
            name: http
        selector:
          app: hello-world
      

      The service manifest has four main sections:

      • metadata tells Kubernetes how to name your service.
      • type tells Kubernetes how you want to expose your service. In this case, it will expose it externally through a Digital Ocean Load Balancer.
      • The ports label tells Kubernetes which ports you want to expose, and how to map them to your deployment. In this case, you will expose port 80 externally and direct it to port 8080 in your deployment.
      • selector tells Kubernetes how to direct traffic. In this case, any pod with the app: hello-world label will receive traffic.

      You now have everything ready to deploy your “Hello World” application on Kubernetes. We will do this next.

      Step 2 — Deploying Your Hello World Application

      In this step you’ll deploy your “Hello World” application on Kubernetes, and then you’ll validate that it is working correctly.

      Start by deploying your application on Kubernetes:

      You’ll see the following output:

      Output

      deployment.apps "hello-world" created service "hello-world" created

      After about one minute or so, you will be able to retrieve your application’s IP. Use this kubectl command to check your service:

      • kubectl get service hello-world

      You’ll see an output like this listing your Kubernetes service objects. Note your application’s IP in the the EXTERNAL-IP column:

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hello-world ClusterIP your_cluster_ip your_external_ip 8080/TCP 37s

      Open your browser and go to your_external_ip listed for your “Hello World” application. Confirm that your application is up and running before continuing with the next step.

      Hello World Okteto

      Until this moment, you’ve followed a fairly traditional pathway for developing applications with Kubernetes. Moving forward, whenever you want to change the code in your application, you’ll have to build and push a new Docker image, and then pull that image from Kubernetes. This process can take quite some time. Okteto was designed to streamline this development inner-loop. Let’s look at the Okteto CLI and see just how it can help.

      Step 3 — Installing the Okteto CLI

      You will now improve your Kubernetes development productivity by installing the Okteto CLI. The Okteto command line interface is an open-source project that lets you synchronize application code changes to an application running on Kubernetes. You can continue using your favorite IDE, debuggers, or compilers without having to commit, build, push, or redeploy containers to test your application–as you did in the previous steps.

      To install the Okteto CLI on a macOS or Linux machine, run the following command:

      • curl https://get.okteto.com -sSfL | sh

      Let’s take a closer look at this command:

      • The curl command is used to transfer data to and from a server.
      • The -s flag suppresses any output.
      • The -S flag shows errors.
      • The -f flag causes the request to fail on HTTP errors.
      • The -L flag makes the request follow redirects.
      • The | operator pipes this output to the sh command, which will download and install the latest okteto binary in your local machine.

      If you are running Windows, you can alternately download the file through your web browser and manually add it to your $PATH.

      Once the Okteto CLI is installed, you are ready to put your “Hello World” application in development mode.

      Step 4 — Putting Your Hello World Application in Development Mode

      The Okteto CLI is designed to swap the application running on a Kubernetes cluster with the code you have in your machine. To do so, Okteto uses the information provided from an Okteto manifest file. This file declares the Kubernetes deployment object that will swap with your local code.

      Create a new file called okteto.yaml with your favorite IDE or text editor:

      Let’s write a basic manifest where you define the deployment object name, the Docker base image to use, and a shell. We will return to this information later. Use the following sample content file:

      okteto.yaml

      name: hello-world
      image: okteto/golang:1
      workdir: /app
      command: ["bash"]
      

      Prepare to put your application in development mode by running the following command:

      Output

      ✓ Development environment activated ✓ Files synchronized Namespace: default Name: hello-world Welcome to your development environment. Happy coding! default:hello-world /app>

      The okteto up command swaps the “Hello World” application into a development environment, which means:

      • The Hello World application container is updated with the docker image okteto/golang:1. This image contains the required dev tools to build, test, debug, and run the “Hello World” application.

      • A file synchronization service is created to keep your changes up-to-date between your local filesystem and your application pods.

      • A remote shell starts in your development environment. Now you can build, test, and run your application as if you were in your local machine.

      • Whatever process you run in the remote shell will get the same incoming traffic, the same environment variables, volumes, or secrets as the original “Hello World” application pods. This, in turn, gives you a highly realistic, production-like development environment.

      In the same console, now run the application as you would typically do (without building and pushing a Docker image), like this:

      Output

      Starting hello-world server...

      The first time you run the application, Go will download your dependencies and compile your application. Wait for this process to finish and test your application by opening your browser and refreshing the page of your application, just as you did previously.

      Now you are ready to begin developing directly on Kubernetes.

      Step 5 — Developing Directly on Kubernetes

      Let’s start making changes to the “Hello World” application and then see how these changes get reflected in Kubernetes.

      Open the main.go file with your favorite IDE or text editor. For example, open a separate console and run the following command:

      Then, change your response message to Hello world from DigitalOcean!:

      main.go

      package main
      
      import (
          "fmt"
          "net/http"
      )
      
      func main() {
          fmt.Println("Starting hello-world server...")
          http.HandleFunc("/", helloServer)
          if err := http.ListenAndServe(":8080", nil); err != nil {
              panic(err)
          }
      }
      
      func helloServer(w http.ResponseWriter, r *http.Request) {
          fmt.Fprint(w, "Hello world from DigitalOcean!")
      }
      

      It is here that your workflow changes. Instead of building images and redeploying containers to update the “Hello World” application, Okteto will synchronize your changes to your development environment on Kubernetes.

      From the console where you executed the okteto up command, cancel the execution of go run main.go by pressing CTRL + C. Now rerun the application:

      • default:hello-world /app> go run main.go

      Output

      Starting hello-world server...

      Go back to the browser and reload the page for your “Hello World” application.

      Hello world DigitalOcean

      Your code changes were applied instantly to Kubernetes, and all without requiring any commits, builds, or pushes.

      Conclusion

      Okteto transforms your Kubernetes cluster into a fully-featured development platform with the click of a button. In this tutorial you installed and configured the Okteto CLI to iterate your code changes directly on Kubernetes as fast as you can type code. Now you can head over to the Okteto samples repository to see how to use Okteto with different programming languages and debuggers.

      Also, if you share a Kubernetes cluster with your team, consider giving each member access to a secure Kubernetes namespace, configured to be isolated from other developers working on the same cluster. This great functionality is also provided by the Okteto App in the DigitalOcean Kubernetes Marketplace.



      Source link

      How To Install and Configure Laravel with Nginx on Ubuntu 20.04


      Not using Ubuntu 20.04?


      Choose a different version or distribution.

      Introduction

      Laravel is an open-source PHP framework that provides a set of tools and resources to build modern PHP applications. With a complete ecosystem leveraging its built-in features, Laravel’s popularity has grown rapidly in the past few years, with many developers adopting it as their framework of choice for a streamlined development process.

      In this guide, you’ll install and configure a new Laravel application on an Ubuntu 20.04 server, using Composer to download and manage the framework dependencies and Nginx to serve the application. When you’re finished, you’ll have a functional Laravel demo application pulling content from a MySQL 8 database.

      Prerequisites

      In order to complete this guide, you will first need to perform the following tasks on your Ubuntu 20.04 server:

      Step 1 — Installing Required PHP modules

      Before you can install Laravel, you need to install a few PHP modules that are required by the framework. We’ll use apt to install the php-mbstring, php-xml and php-bcmath PHP modules. These PHP extensions provide extra support for dealing with character encoding, XML and precision mathematics.

      If this is the first time using apt in this session, you should first run the update command to update the package manager cache:

      Now you can install the required packages with:

      • sudo apt install php-mbstring php-xml php-bcmath

      Your system is now ready to execute Laravel’s installation via Composer, but before doing so, you’ll need a database for your application.

      Step 2 — Creating a Database for the Application

      To demonstrate Laravel’s basic installation and usage, we’ll create a travel list application to show a list of places a user would like to travel to, and a list of places that they already visited. This can be stored in a places table with a field for locations that we’ll call name and another field to mark them as visited or not visited, which we’ll call visited. Additionally, we’ll include an id field to uniquely identify each entry.

      To connect to the database from the Laravel application, we’ll create a dedicated MySQL user, and grant this user full privileges over the travellist database.

      At the time of this writing, the native MySQL PHP library mysqlnd doesn’t support caching_sha2_authentication, the default authentication method for MySQL 8. We’ll need to set up our database user with the mysql_native_password authentication method in order to be able to connect to the MySQL database from PHP.

      To get started, log in to the MySQL console as the root database user with:

      To create a new database, run the following command from your MySQL console:

      • CREATE DATABASE travellist;

      Now you can create a new user and grant them full privileges on the custom database you’ve just created. In this example, we’re creating a user named travellist_user with the password password, though you should change this to a secure password of your choosing:

      • CREATE USER 'travellist_user'@'%' IDENTIFIED WITH mysql_native_password BY 'password';

      Now we need to give this user permission over the travellist database:

      • GRANT ALL ON travellist.* TO 'travellist_user'@'%';

      This will give the travellist_user user full privileges over the travellist database, while preventing this user from creating or modifying other databases on your server.

      Following this, exit the MySQL shell:

      You can now test if the new user has the proper permissions by logging in to the MySQL console again, this time using the custom user credentials:

      • mysql -u travellist_user -p

      Note the -p flag in this command, which will prompt you for the password used when creating the travellist_user user. After logging in to the MySQL console, confirm that you have access to the travellist database:

      This will give you the following output:

      Output

      +--------------------+ | Database | +--------------------+ | information_schema | | travellist | +--------------------+ 2 rows in set (0.01 sec)

      Next, create a table named places in the travellist database. From the MySQL console, run the following statement:

      • CREATE TABLE travellist.places (
      • id INT AUTO_INCREMENT,
      • name VARCHAR(255),
      • visited BOOLEAN,
      • PRIMARY KEY(id)
      • );

      Now, populate the places table with some sample data:

      • INSERT INTO travellist.places (name, visited)
      • VALUES ("Tokyo", false),
      • ("Budapest", true),
      • ("Nairobi", false),
      • ("Berlin", true),
      • ("Lisbon", true),
      • ("Denver", false),
      • ("Moscow", false),
      • ("Olso", false),
      • ("Rio", true),
      • ("Cincinnati", false),
      • ("Helsinki", false);

      To confirm that the data was successfully saved to your table, run:

      • SELECT * FROM travellist.places;

      You will see output similar to this:

      Output

      +----+-----------+---------+ | id | name | visited | +----+-----------+---------+ | 1 | Tokyo | 0 | | 2 | Budapest | 1 | | 3 | Nairobi | 0 | | 4 | Berlin | 1 | | 5 | Lisbon | 1 | | 6 | Denver | 0 | | 7 | Moscow | 0 | | 8 | Oslo | 0 | | 9 | Rio | 1 | | 10 | Cincinnati| 0 | | 11 | Helsinki | 0 | +----+-----------+---------+ 11 rows in set (0.00 sec)

      After confirming that you have valid data in your test table, you can exit the MySQL console:

      You’re now ready to create the application and configure it to connect to the new database.

      Step 3 — Creating a New Laravel Application

      You will now create a new Laravel application using the composer create-project command. This Composer command is typically used to bootstrap new applications based on existing frameworks and content management systems.

      Throughout this guide, we’ll use travellist as an example application, but you are free to change this to something else. The travellist application will display a list of locations pulled from a local MySQL server, intended to demonstrate Laravel’s basic configuration and confirm that you’re able to connect to the database.

      First, go to your user’s home directory:

      The following command will create a new travellist directory containing a barebones Laravel application based on default settings:

      • composer create-project --prefer-dist laravel/laravel travellist

      You will see output similar to this:

      Output

      Installing laravel/laravel (v5.8.17) - Installing laravel/laravel (v5.8.17): Downloading (100%) Created project in travellist > @php -r "file_exists('.env') || copy('.env.example', '.env');" Loading composer repositories with package information Updating dependencies (including require-dev) Package operations: 80 installs, 0 updates, 0 removals - Installing symfony/polyfill-ctype (v1.11.0): Downloading (100%) - Installing phpoption/phpoption (1.5.0): Downloading (100%) - Installing vlucas/phpdotenv (v3.4.0): Downloading (100%) - Installing symfony/css-selector (v4.3.2): Downloading (100%) ...

      When the installation is finished, access the application’s directory and run Laravel’s artisan command to verify that all components were successfully installed:

      • cd travellist
      • php artisan

      You’ll see output similar to this:

      Output

      Laravel Framework 7.11.0 Usage: command [options] [arguments] Options: -h, --help Display this help message -q, --quiet Do not output any message -V, --version Display this application version --ansi Force ANSI output --no-ansi Disable ANSI output -n, --no-interaction Do not ask any interactive question --env[=ENV] The environment the command should run under -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug ...

      This output confirms that the application files are in place, and the Laravel command-line tools are working as expected. However, we still need to configure the application to set up the database and a few other details.

      Step 4 — Configuring Laravel

      The Laravel configuration files are located in a directory called config, inside the application’s root directory. Additionally, when you install Laravel with Composer, it creates an environment file. This file contains settings that are specific to the current environment the application is running, and will take precedence over the values set in regular configuration files located at the config directory. Each installation on a new environment requires a tailored environment file to define things such as database connection settings, debug options, application URL, among other items that may vary depending on which environment the application is running.

      Warning: The environment configuration file contains sensitive information about your server, including database credentials and security keys. For that reason, you should never share this file publicly.

      We’ll now edit the .env file to customize the configuration options for the current application environment.

      Open the .env file using your command line editor of choice. Here we’ll use nano:

      Even though there are many configuration variables in this file, you don’t need to set up all of them now. The following list contains an overview of the variables that require immediate attention:

      • APP_NAME: Application name, used for notifications and messages.
      • APP_ENV: Current application environment.
      • APP_KEY: Used for generating salts and hashes, this unique key is automatically created when installing Laravel via Composer, so you don’t need to change it.
      • APP_DEBUG: Whether or not to show debug information at client side.
      • APP_URL: Base URL for the application, used for generating application links.
      • DB_DATABASE: Database name.
      • DB_USERNAME: Username to connect to the database.
      • DB_PASSWORD: Password to connect to the database.

      By default, these values are configured for a local development environment that uses Homestead, a prepackaged Vagrant box provided by Laravel. We’ll change these values to reflect the current environment settings of our example application.

      In case you are installing Laravel in a development or testing environment, you can leave the APP_DEBUG option enabled, as this will give you important debug information while testing the application from a browser. The APP_ENV variable should be set to development or testing in this case.

      In case you are installing Laravel in a production environment, you should disable the APP_DEBUG option, because it shows to the final user sensitive information about your application. The APP_ENV in this case should be set to production.

      The following .env file sets up our example application for development:

      Note: The APP_KEY variable contains a unique key that was auto generated when you installed Laravel via Composer. You don’t need to change this value. If you want to generate a new secure key, you can use the php artisan key:generate command.

      /var/www/travellist/.env

      APP_NAME=TravelList
      APP_ENV=development
      APP_KEY=APPLICATION_UNIQUE_KEY_DONT_COPY
      APP_DEBUG=true
      APP_URL=http://domain_or_IP
      
      LOG_CHANNEL=stack
      
      DB_CONNECTION=mysql
      DB_HOST=127.0.0.1
      DB_PORT=3306
      DB_DATABASE=travellist
      DB_USERNAME=travellist_user
      DB_PASSWORD=password
      
      ...
      

      Adjust your variables accordingly. When you are done editing, save and close the file to keep your changes. If you’re using nano, you can do that with CTRL+X, then Y and Enter to confirm.

      Your Laravel application is now set up, but we still need to configure the web server in order to be able to access it from a browser. In the next step, we’ll configure Nginx to serve your Laravel application.

      Step 5 — Setting Up Nginx

      We have installed Laravel on a local folder of your remote user’s home directory, and while this works well for local development environments, it’s not a recommended practice for web servers that are open to the public internet. We’ll move the application folder to /var/www, which is the usual location for web applications running on Nginx.

      First, use the mv command to move the application folder with all its contents to /var/www/travellist:

      • sudo mv ~/travellist /var/www/travellist

      Now we need to give the web server user write access to the storage and cache folders, where Laravel stores application-generated files:

      • sudo chown -R www-data.www-data /var/www/travellist/storage
      • sudo chown -R www-data.www-data /var/www/travellist/bootstrap/cache

      The application files are now in order, but we still need to configure Nginx to serve the content. To do this, we’ll create a new virtual host configuration file at /etc/nginx/sites-available:

      • sudo nano /etc/nginx/sites-available/travellist

      The following configuration file contains the recommended settings for Laravel applications on Nginx:

      /etc/nginx/sites-available/travellist

      server {
          listen 80;
          server_name server_domain_or_IP;
          root /var/www/travellist/public;
      
          add_header X-Frame-Options "SAMEORIGIN";
          add_header X-XSS-Protection "1; mode=block";
          add_header X-Content-Type-Options "nosniff";
      
          index index.html index.htm index.php;
      
          charset utf-8;
      
          location / {
              try_files $uri $uri/ /index.php?$query_string;
          }
      
          location = /favicon.ico { access_log off; log_not_found off; }
          location = /robots.txt  { access_log off; log_not_found off; }
      
          error_page 404 /index.php;
      
          location ~ .php$ {
              fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
              fastcgi_index index.php;
              fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
              include fastcgi_params;
          }
      
          location ~ /.(?!well-known).* {
              deny all;
          }
      }
      

      Copy this content to your /etc/nginx/sites-available/travellist file and, if necessary, adjust the highlighted values to align with your own configuration. Save and close the file when you’re done editing.

      To activate the new virtual host configuration file, create a symbolic link to travellist in sites-enabled:

      • sudo ln -s /etc/nginx/sites-available/travellist /etc/nginx/sites-enabled/

      Note: If you have another virtual host file that was previously configured for the same server_name used in the travellist virtual host, you might need to deactivate the old configuration by removing the corresponding symbolic link inside /etc/nginx/sites-enabled/.

      To confirm that the configuration doesn’t contain any syntax errors, you can use:

      You should see output like this:

      Output

      • nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
      • nginx: configuration file /etc/nginx/nginx.conf test is successful

      To apply the changes, reload Nginx with:

      • sudo systemctl reload nginx

      Now go to your browser and access the application using the server’s domain name or IP address, as defined by the server_name directive in your configuration file:

      http://server_domain_or_IP
      

      You will see a page like this:

      Laravel splash page

      That confirms your Nginx server is properly configured to serve Laravel. From this point, you can start building up your application on top of the skeleton provided by the default installation.

      In the next step, we’ll modify the application’s main route to query for data in the database using Laravel’s DB facade.

      Step 6 — Customizing the Main Page

      Assuming you’ve followed all the steps in this guide so far, you should have a working Laravel application and a database table named places containing some sample data.

      We’ll now edit the main application route to query for the database and return the contents to the application’s view.

      Open the main route file, routes/web.php:

      This file comes by default with the following content:

      routes/web.php

      <?php
      
      /*
      |--------------------------------------------------------------------------
      | Web Routes
      |--------------------------------------------------------------------------
      |
      | Here is where you can register web routes for your application. These
      | routes are loaded by the RouteServiceProvider within a group which
      | contains the "web" middleware group. Now create something great!
      |
      */
      
      Route::get('/', function () {
          return view('welcome');
      });
      
      

      Routes are defined within this file using the static method Route::get, which receives a path and a callback function as arguments.

      The following code replaces the main route callback function. It makes 2 queries to the database using the visited flag to filter results. It returns the results to a view named travellist, which we’re going to create next. Copy this content to your routes/web.php file, replacing the code that is already there:

      routes/web.php

      <?php
      
      use IlluminateSupportFacadesDB;
      
      Route::get('/', function () {
        $visited = DB::select('select * from places where visited = ?', [1]); 
        $togo = DB::select('select * from places where visited = ?', [0]);
      
        return view('travellist', ['visited' => $visited, 'togo' => $togo ] );
      });
      

      Save and close the file when you’re done editing. We’ll now create the view that will render the database results to the user. Create a new view file inside resources/views:

      • nano resources/views/travellist.blade.php

      The following template creates two lists of places based on the variables visited and togo. Copy this content to your new view file:

      resources/views/travellist/blade.php

      <html>
      <head>
          <title>Travel List</title>
      </head>
      
      <body>
          <h1>My Travel Bucket List</h1>
          <h2>Places I'd Like to Visit</h2>
          <ul>
            @foreach ($togo as $newplace)
              <li>{{ $newplace->name }}</li>
            @endforeach
          </ul>
      
          <h2>Places I've Already Been To</h2>
          <ul>
                @foreach ($visited as $place)
                      <li>{{ $place->name }}</li>
                @endforeach
          </ul>
      </body>
      </html>
      

      Save and close the file when you’re done. Now go to your browser and reload the application. You’ll see a page like this:

      Demo Laravel Application

      You have now a functional Laravel application pulling contents from a MySQL database.

      Conclusion

      In this tutorial, you’ve set up a new Laravel application on top of a LEMP stack (Linux, Nginx, MySQL and PHP), running on an Ubuntu 20.04 server. You’ve also customized your default route to query for database content and exhibit the results in a custom view.

      From here, you can create new routes and views for any additional pages your application needs. Check the official Laravel documentation for more information on routes, views, and database support. If you’re deploying to production, you should also check the optimization section for a few different ways in which you can improve your application’s performance.



      Source link

      Cómo crear componentes personalizados en React


      El autor seleccionó Creative Commons para recibir una donación como parte del programa Write for DOnations.

      Introducción

      En este tutorial, aprenderá a crear componentes personalizados en React. Los componentes son elementos de funcionalidad independientes que puede reutilizar en sus aplicaciones, y son las unidades estructurales básicas de todas las aplicaciones de React. A menudo, pueden ser simples clases y funciones de JavaScript, pero se los utiliza como si fueran elementos HTML personalizados. Los botones, los menús y cualquier otro contenido de las páginas de front-end pueden crearse como componentes. Los componentes también pueden contener información de estado y mostrar marcado.

      Una vez que aprenda a crear componentes en React, podrá dividir aplicaciones complejas en pequeñas piezas más fáciles de compilar y mantener.

      En este tutorial, creará una lista de emojis que mostrarán sus nombres cuando se hace clic en ellos. Los emojis se crearán usando un componente personalizado y se los invocará desde el interior de otro componente personalizado. Al final de este tutorial, habrá creado componentes personalizados utilizando clases y funciones de JavaScript, y sabrá cómo separar código existente en elementos reutilizables y cómo almacenar los componentes en una estructura de archivos legible.

      Requisitos previos

      Paso 1: Configurar el proyecto React

      En este paso, creará una base para su proyecto usando Create React App. También modificará el proyecto predeterminado para crear su proyecto de base al asignar una lista de emojis y añadir algo de estilo.

      Primero, cree un proyecto nuevo. Abra un terminal y, luego, ejecute el siguiente comando:

      • npx create-react-app tutorial-03-component

      Una vez completado, pase al directorio del proyecto:

      Abra el código App.js en un editor de texto:

      A continuación, elimine el código de la plantilla creado por Create React App y sustituya el contenido por el nuevo código de React que muestra una lista de emojis:

      tutorial-03-component/src/App.js

      import React from 'react';
      import './App.css';
      
      const displayEmojiName = event => alert(event.target.id);
      const emojis = [
        {
          emoji: '😀',
          name: "test grinning face"
        },
        {
          emoji: '🎉',
          name: "party popper"
        },
        {
          emoji: '💃',
          name: "woman dancing"
        }
      ];
      
      function App() {
        const greeting = "greeting";
        const displayAction = false;
        return(
          <div className="container">
            <h1 id={greeting}>Hello, World</h1>
            {displayAction && <p>I am writing JSX</p>}
            <ul>
              {
                emojis.map(emoji => (
                  <li key={emoji.name}>
                    <button
                      onClick={displayEmojiName}
                    >
                      <span role="img" aria-label={emoji.name} id={emoji.name}>{emoji.emoji}</span>
                    </button>
                  </li>
                ))
              }
            </ul>
          </div>
        )
      }
      
      export default App;
      

      Este código utiliza la sintaxis de JSX para hacer map() sobre la matriz de emojis y enumerarlos como elementos de la lista <li>. También adjunta eventos onClick para mostrar datos de los emojis en el navegador. Para analizar el código con mayor detenimiento, consulte Cómo crear elementos de React con JSX, que contiene una explicación detallada de JSX.

      Guarde y cierre el archivo. Ahora, puede eliminar el archivo logo.svg, dado que era parte de la plantilla y ya no está haciendo referencia a ella:

      A continuación, actualice el estilo. Abra src/App.css:

      Sustituya el contenido por el siguiente CSS para centrar los elementos y ajustar la fuente:

      tutorial-03-component/src/App.css

      .container {
          display: flex;
          flex-direction: column;
          align-items: center;
      }
      
      button {
          font-size: 2em;
          border: 0;
          padding: 0;
          background: none;
          cursor: pointer;
      }
      
      ul {
          display: flex;
          padding: 0;
      }
      
      li {
          margin: 0 20px;
          list-style: none;
          padding: 0;
      }
      

      Se utiliza flex para centrar la <h1> principal y enumerar los elementos. También elimina estilos de botones predeterminados y de <li> para que los emojis se alineen en una fila. Puede encontrar más detalles en Cómo crear elementos de React con JSX.

      Guarde el archivo y ciérrelo.

      Abra otra ventana de terminal en el root de su proyecto. Inicie el proyecto con el siguiente comando:

      Una vez que el comando se ejecute, verá el proyecto en ejecución en su navegador web en http://localhost:3000.

      Déjelo en ejecución todo el tiempo que esté trabajando en su proyecto. Cada vez que guarde el proyecto, el navegador se actualizará de forma automática y mostrará el código más actualizado.

      Verá la página de su proyecto con Hello, World y los tres emojis que enumeró en su archivo App.js:

      Navegador con emoji

      Ahora que configuró su código, puede comenzar a unir componentes en React.

      Paso 2: Crear un componente independiente con clases de React

      Ahora que su proyecto se está ejecutando, puede comenzar a crear su componente personalizado. En este paso, creará un componente de React independiente ampliando la clase Component de React. Creará una nueva clase, agregará métodos y usará la función de representación para mostrar datos.

      Los componentes de React son elementos autónomos que puede reutilizar en una página. Al crear pequeñas piezas de código centradas, las puede mover y reutilizar a medida que su aplicación se amplía. La clave es que son autónomas y centradas, lo que le permite separar el código en piezas lógicas. De hecho, ya ha estado trabajando con componentes que se separan de forma lógica: el archivo App.js es un componente funcional, que verá en más detalle en el paso 3.

      Hay dos tipos de componentes personalizados: basados en clases y funcionales. El primer componente que va a crear es un componente basado en clases. Creará un nuevo componente denominado Instructions que explica las instrucciones del visor de emojis.

      Nota: Los componentes basados en clases solían ser la forma más popular de crear componentes de React. Pero con la introducción de los hooks de React, muchos desarrolladores y bibliotecas están comenzando a usar componentes funcionales.

      Si bien, ahora, los componentes funcionales son la norma, a menudo, encontrará componentes de clases en código heredado. No es necesario que los use, pero sí que sepa reconocerlos. También ofrecen una introducción clara a muchos conceptos futuros, como la gestión de estados. En este tutorial, aprenderá a crear componentes funcionales y de clase.

      Para comenzar, cree un archivo nuevo. Por convención, los archivos de componentes se escriben con mayúscula:

      • touch src/Instructions.js

      Luego, abra el archivo en su editor de texto:

      Primero, importe React y la clase Component y exporte Instructions con las siguientes líneas:

      tutorial-03-component/src/Instructions.js

      import React, { Component } from 'react';
      
      export default class Instructions extends Component {}
      

      La importación de React convertirá el JSX. Component es una clase de base que ampliará para crear su componente. Para ampliarlo, creó una clase que tiene el nombre de su componente (Instructions) y extendió la clase Component de base con la línea export. También está exportando esta clase como predeterminada con las palabras export default al comienzo de la declaración de clase.

      El nombre de la clase se debe escribir con mayúscula y debe coincidir con el nombre del archivo. Esto es importante cuando se utilizan herramientas de depuración, que mostrarán el nombre del componente. Si el nombre coincide con la estructura de archivos, será más fácil localizar el componente en cuestión.

      La clase Component de base tiene varios métodos que puede usar en su clase personalizada. El más importante, y el único que usará en este tutorial, es el método render(). El método render() devuelve el código JSX que desea mostrar en el navegador.

      Para comenzar, añada una pequeña explicación de la aplicación en una etiqueta <p>:

      tutorial-03-component/src/Instructions.js

      import React, { Component } from 'react';
      
      export class Instructions extends Component {
      
        render() {
          return(
            <p>Click on an emoji to view the emoji short name.</p>
          )
        }
      
      }
      

      Guarde y cierre el archivo. En este momento, todavía no hay cambios en su navegador. Esto se debe a que todavía no utilizó el componente nuevo. Para usarlo, deberá añadirlo a otro componente que se conecte con el componente root. En este proyecto, <App> es el componente root en index.js. Para que aparezca en su aplicación, deberá añadirlo al componente <App>.

      Abra src/App.js en un editor de texto:

      Primero, deberá importar el componente:

      tutorial-03-component/src/App.js

      import React from 'react';
      
      import Instructions from './Instructions';
      
      import './App.css';
      
      ...
      
      export default App;
      

      Como es la importación predeterminada, puede importar a cualquier nombre que desee. Es mejor mantener los nombres consistentes por motivos de legibilidad: la importación debe coincidir con el nombre del componente, que, a su vez, debe coincidir con el nombre del archivo. Pero la única regla fija es que el componente debe comenzar con una letra mayúscula. Así es como React sabe que se trata de un componente de React.

      Ahora que importó el componente, añádalo al resto de su código, como si fuera un elemento HTML personalizado:

      tutorial-03-component/src/App.js

      import React from 'react';
      
      import Instructions from './Instructions.js'
      
      ...
      function App() {
        const greeting = "greeting";
        const displayAction = false;
        return(
          <div className="container">
            <h1 id={greeting}>Hello, World</h1>
            {displayAction && <p>I am writing JSX</p>}
            <Instructions />
            <ul>
              {
                emojis.map(emoji => (
                  <li key={emoji.name}>
                    <button
                      onClick={displayEmojiName}
                    >
                      <span role="img" aria-label={emoji.name} id={emoji.name}>{emoji.emoji}</span>
                    </button>
                  </li>
                ))
              }
            </ul>
          </div>
        )
      }
      
      export default App;
      

      En este código, encerró el componente entre corchetes angulares. Como este componente no tiene elementos secundarios, se puede cerrar de forma automática al terminar con />.

      Guarde el archivo. Al hacerlo, la página se actualizará y verá el componente nuevo.

      Navegador con texto de instrucción

      Ahora que tiene algo de texto, puede añadir una imagen. Descargue una imagen de emoji de wikimedia y guárdela en el directorio src como emoji.svg con el siguiente comando:

      • curl -o src/emoji.svg https://upload.wikimedia.org/wikipedia/commons/3/33/Twemoji_1f602.svg

      curl realiza la solicitud a la URL y el indicador -o le permite guardar el archivo como src/emoji.svg.

      A continuación, abra el archivo de su componente:

      Importe el emoji y añádalo a su componente personalizado con un enlace dinámico:

      tutorial-03-component/src/Instructions.js

      import React, { Component } from 'react';
      import emoji from './emoji.svg'
      
      export default class Instructions extends Component {
      
        render() {
          return(
            <>
              <img alt="laughing crying emoji" src={emoji} />
              <p>Click on an emoji to view the emoji short name.</p>
            </>
          )
        }
      }
      

      Tenga en cuenta que debe incluir la extensión del archivo .svg al realizar la importación. Al importar, importa una ruta dinámica que crea webpack cuando se compila el código. Para obtener más información, consulte Cómo configurar un proyecto de React con Create React App.

      También deberá envolver las etiquetas <img> y <p> con etiquetas vacías para asegurarse de que se devuelva un único elemento.

      Guarde el archivo. Al volver a cargar el navegador, la imagen será muy grande en comparación con el resto del contenido:

      Ventana de navegador con una imagen de emoji grande

      Para reducir el tamaño de la imagen, deberá añadir algo de CSS y un className a su componente personalizado.

      Primero, en Instructions.js, cambie las etiquetas vacías por div y asigne un className de instructions:

      tutorial-03-component/src/Instructions.js

      import React, { Component } from 'react';
      import emoji from './emoji.svg'
      
      export default class Instructions extends Component {
      
        render() {
          return(
            <div className="instructions">
              <img alt="laughing crying emoji" src={emoji} />
              <p>Click on an emoji to view the emoji short name.</p>
            </div>
          )
        }
      }
      

      Guarde y cierre el archivo. A continuación, abra App.css:

      Cree reglas para el selector de clases .instructions:

      tutorial-03-component/src/App.css

      .container {
          display: flex;
          flex-direction: column;
          align-items: center;
      }
      
      ...
      
      .instructions {
          display: flex;
          flex-direction: column;
          align-items: center;
      }
      

      Al añadir un display de estilo flex, hace que img y p se centren con flexbox. Cambió la dirección para que todo se alinee verticalmente con flex-direction: column;. La línea align-items: center; centrará los elementos en la pantalla.

      Ahora que los elementos están alineados, deberá cambiar el tamaño de la imagen. Asigne a img dentro de div un valor de width (ancho) y height (alto) de 100 px.

      tutorial-03-component/src/App.css

      .container {
          display: flex;
          flex-direction: column;
          align-items: center;
      }
      
      ...
      
      .instructions {
          display: flex;
          flex-direction: column;
          align-items: center;
      }
      
      .instructions img {
          width: 100px;
          height: 100px;
      }
      

      Guarde y cierre el archivo. El navegador se volverá a cargar y verá que la imagen es mucho más pequeña:

      Ventana de navegador con una imagen más pequeña

      En este punto, creó un componente personalizado independiente y reutilizable. Para ver cómo se reutiliza, añada una segunda instancia a App.js.

      Abra App.js:

      En App.js, añada una segunda instancia del componente:

      tutorial-03-component/src/App.js

      import React from 'react';
      
      import Instructions from './Instructions.js'
      
      ...
      
      function App() {
        const greeting = "greeting";
        const displayAction = false;
        return(
          <div className="container">
            <h1 id={greeting}>Hello, World</h1>
            {displayAction && <p>I am writing JSX</p>}
            <Instructions />
            <Instructions />
            <ul>
              {
                emojis.map(emoji => (
                  <li key={emoji.name}>
                    <button
                      onClick={displayEmojiName}
                    >
                      <span role="img" aria-label={emoji.name} id={emoji.name}>{emoji.emoji}</span>
                    </button>
                  </li>
                ))
              }
            </ul>
          </div>
        )
      }
      
      export default App;
      

      Guarde el archivo. Cuando el navegador se vuelva a cargar, verá el componente dos veces.

      Navegador con dos instancias del componente Instructions

      En este caso, no desea dos instancias de Instructions, pero puede ver que el componente se puede reutilizar de forma eficiente. Es probable que use los botones o las tablas personalizados que cree varias veces en una página, por lo que son ideales para usar como componentes personalizados.

      Por ahora, puede eliminar la etiqueta de imagen adicional. En su editor de texto, elimine el segundo <Instructions /> y guarde el archivo:

      tutorial-03-component/src/App.js

      import React from 'react';
      
      import Instructions from './Instructions.js'
      
      ...
      
      function App() {
        const greeting = "greeting";
        const displayAction = false;
        return(
          <div className="container">
            <h1 id={greeting}>Hello, World</h1>
            {displayAction && <p>I am writing JSX</p>}
            <Instructions />
            <ul>
              {
                emojis.map(emoji => (
                  <li key={emoji.name}>
                    <button
                      onClick={displayEmojiName}
                    >
                      <span role="img" aria-label={emoji.name} id={emoji.name}>{emoji.emoji}</span>
                    </button>
                  </li>
                ))
              }
            </ul>
          </div>
        )
      }
      
      export default App;
      

      Ahora, tiene un componente independiente y reutilizable que puede añadir a un componente principal varias veces. La estructura que tiene ahora funciona para un número reducido de componentes, pero hay un pequeño problema: todos los archivos están mezclados. La imagen de <Instructions> se encuentra en el mismo directorio que los recursos de <App>. También se está mezclando el código CSS de <App> con el de <Instructions>.

      En el siguiente paso, creará una estructura de archivos que le dará independencia a cada componente al agrupar sus funcionalidades, estilos y dependencias, lo que le permitirá moverlos según sea necesario.

      Paso 3: Crear una estructura de archivos legible

      En este paso, creará una estructura de archivos para organizar sus componentes y recursos, como imágenes, código CSS y otros archivos de JavaScript. Agrupará el código por componentes, no por tipo de recursos. En otras palabras, no tendrá un directorio separado para CSS, imágenes y JavaScript. En su lugar, tendrá un directorio independiente para cada componente que contendrá CSS, JavaScript e imágenes pertinentes. En los dos casos, está separando cuestiones.

      Como tiene un componente independiente, necesita una estructura de archivos que agrupe el código pertinente. En este momento, todo se encuentra en el mismo directorio. Enumere los elementos en su directorio src:

      El resultado indica que todo se está desordenando bastante:

      Output

      App.css Instructions.js index.js App.js emoji.svg serviceWorker.js App.test.js index.css setupTests.js

      Tiene el código del componente <App> (App.css, App.js y App.test.js) junto a su componente root (index.css e index.js) y su componente personalizado Instructions.js.

      React es intencionalmente independiente de la estructura de archivos. No recomienda ninguna estructura en particular y el proyecto puede funcionar con diversas jerarquías de archivos. Sin embargo, recomendamos añadir cierto orden para evitar sobrecargar el directorio root con componentes, archivos CSS e imágenes que serán difíciles de navegar. Además, usar una nomenclatura explícita puede facilitar la visualización de las piezas de su proyecto que están relacionadas.  Por ejemplo, puede no ser claro que un archivo de imagen denominado Logo.svg es parte de un componente llamado Header.js.

      Una de las estructuras más simples es la creación de un directorio components con un directorio separado para cada componente. Esto le permitirá agrupar sus componentes de forma separada del código de configuración, como serviceWorker, y, a la vez, agrupar los recursos con los componentes.

      Crear un directorio components

      Para comenzar, cree un directorio denominado components:

      A continuación, pase los siguientes componentes y código al directorio: App.css, App.js, App.test.js, Instructions.js y emoji.svg:

      • mv src/App.* src/components/
      • mv src/Instructions.js src/components/
      • mv src/emoji.svg src/components/

      Aquí, está usando un carácter comodín (*) para seleccionar todos los archivos que se comienzan con App.

      Después de trasladar el código, verá un error en su terminal que ejecuta npm start.

      Output

      Failed to compile. ./src/App.js Error: ENOENT: no such file or directory, open 'your_file_path/tutorial-03-component/src/App.js'

      Recuerde que todo el código está importando usando rutas relativas. Si cambia la ruta de ciertos archivos, deberá actualizar el código.

      Para hacerlo, abra index.js.

      Luego, cambie la ruta de la importación de App para que importe desde el directorio components/.

      tutorial-03-component/src/index.js

      import React from 'react';
      import ReactDOM from 'react-dom';
      import './index.css';
      import App from './components/App';
      import * as serviceWorker from './serviceWorker';
      
      ...
      
      serviceWorker.unregister();
      

      Guarde y cierre el archivo. Su secuencia de comandos detectará los cambios, y el error desaparecerá.

      Ahora, tiene componentes en un directorio separado. A medida que sus aplicaciones se vuelven más complejas, es posible que tenga directorios para servicios API, almacenes de datos y funciones de utilidad. Separar el código de los componentes es el primer paso, pero todavía tiene el código CSS de Instructions mezclado en el archivo App.css.  Para crear esta separación lógica, primero, trasladará los componentes a directorios separados.

      Trasladar componentes a directorios individuales

      Primero, cree un directorio específicamente para el componente <App>:

      Luego, traslade los archivos relacionados al directorio nuevo:

      • mv src/components/App.* src/components/App

      Al hacerlo, obtendrá un error similar al de la última sección:

      Output

      Failed to compile. ./src/components/App.js Error: ENOENT: no such file or directory, open 'your_file_path/tutorial-03-component/src/components/App.js'

      En este caso, deberá actualizar dos cosas. Primero, deberá actualizar la ruta en index.js.

      Abra el archivo index.js:

      Luego, actualice la ruta de importación de App para que apunte al componente App en el directorio App.

      tutorial-03-component/src/index.js

      import React from 'react';
      import ReactDOM from 'react-dom';
      import './index.css';
      import App from './components/App/App';
      import * as serviceWorker from './serviceWorker';
      
      ...
      
      serviceWorker.unregister();
      

      Guarde y cierre el archivo. La aplicación seguirá sin ejecutarse. Verá un error como este:

      Output

      Failed to compile. ./src/components/App/App.js Module not found: Can't resolve './Instructions.js' in 'your_file_path/tutorial-03-component/src/components/App'

      Como <Instructions> no se encuentra en el mismo nivel de directorio que el componente <App>, deberá cambiar la ruta de importación. Antes de hacerlo, cree un directorio para Instructions. Cree un directorio denominado Instructions en el directorio src/components:

      • mkdir src/components/Instructions

      Luego, traslade Instructions.js y emoji.svg a ese directorio:

      • mv src/components/Instructions.js src/components/Instructions
      • mv src/components/emoji.svg src/components/Instructions

      Ahora que se creó el directorio del componente Instructions, puede terminar de actualizar las rutas de archivos para conectar su componente a su aplicación.

      Actualizar rutas de importación

      Ahora que los componentes se encuentran en directorios individuales, puede ajustar la ruta de importación en App.js.

      Abra App.js:

      • nano src/components/App/App.js

      Como la ruta es relativa, deberá subir un directorio, src/components, y, luego, ingresar al directorio Instructions de Instructions.js, pero, como se trata de un archivo JavaScript, no necesita la importación final.

      tutorial-03-component/src/components/App/App.js

      import React from 'react';
      
      import Instructions from '../Instructions/Instructions.js';
      
      import './App.css';
      
      ...
      
      export default App;
      

      Guarde y cierre el archivo. Ahora que todas sus importaciones están usando la ruta correcta, su navegador se actualizará y mostrará la aplicación.

      Ventana de navegador con una imagen más pequeña

      Nota: También puede denominar el archivo root de cada directorio index.js. Por ejemplo, en lugar de src/components/App/App.js, podría crear src/components/App/index.js. La ventaja es que, de esta manera, sus importaciones son ligeramente más pequeñas. Si la ruta apunta a un directorio, la importación buscará un archivo index.js. La importación de src/components/App/index.js en el archivo src/index.js sería import ./components/App. La desventaja de este método es que termina teniendo muchos archivos con el mismo nombre, lo que puede dificultar la lectura en algunos editores de texto. En última instancia, se trata de una decisión personal y de equipo, pero lo mejor es ser coherente.

      Separar código en archivos compartidos

      Ahora, cada componente tiene su propio directorio, pero no todo es completamente independiente. El último paso es extraer el CSS de Instructions a un archivo separado.

      Primero, cree un archivo CSS en src/components/Instructions:

      • touch src/components/Instructions/Instructions.css

      Luego, abra el archivo CSS en su editor de texto:

      • nano src/components/Instructions/Instructions.css

      Añada el CSS de instrucciones que creó en una sección anterior:

      tutorial-03-component/src/components/Instructions/Instructions.css

      .instructions {
          display: flex;
          flex-direction: column;
          align-items: center;
      }
      
      .instructions img {
          width: 100px;
          height: 100px;
      }
      

      Guarde y cierre el archivo. Luego, elimine el CSS de instrucciones de src/components/App/App.css.

      • nano src/components/App/App.css

      Elimine las líneas sobre .instructions. El archivo final tendrá el siguiente aspecto:

      tutorial-03-component/src/components/App/App.css

      .container {
          display: flex;
          flex-direction: column;
          align-items: center;
      }
      
      button {
          font-size: 2em;
          border: 0;
          padding: 0;
          background: none;
          cursor: pointer;
      }
      
      ul {
          display: flex;
          padding: 0;
      }
      
      li {
          margin: 0 20px;
          list-style: none;
          padding: 0;
      }
      

      Guarde y cierre el archivo. Por último, importe el CSS en Instructions.js:

      • nano src/components/Instructions/Instructions.js

      Importe el CSS usando la ruta relativa:

      tutorial-03-component/src/components/Instructions/Instructions.js

      import React, { Component } from 'react';
      import './Instructions.css';
      import emoji from './emoji.svg'
      
      export default class Instructions extends Component {
      
        render() {
          return(
            <div className="instructions">
              <img alt="laughing crying emoji" src={emoji} />
              <p>Click on an emoji to view the emoji short name.</p>
            </div>
          )
        }
      }
      

      Guarde y cierre el archivo. La ventana de su navegador se verá igual que antes, excepto que, ahora, todos los recursos del archivo están agrupados en el mismo directorio.

      Ventana de navegador con una imagen más pequeña

      Ahora, observe la estructura una última vez. Primero, el directorio src/:

      Cuenta con el componente root index.js y el CSS relacionado index.css junto al directorio components/ y archivos de utilidad, como serviceWorker.js y setupTests.js:

      Output

      components serviceWorker.js index.css setupTests.js index.js

      Luego, observe el interior de components:

      Verá un directorio para cada componente:

      Output

      App Instructions

      Si observa el interior de cada componente, verá el código del componente y archivos CSS, de prueba y de imagen, si existen.

      Output

      App.css App.js App.test.js
      • ls src/components/Instructions

      Output

      Instructions.css Instructions.js emoji.svg

      En este punto, creó una estructura sólida para su proyecto. Movió mucho código, pero, ahora que tiene una estructura, se ampliará más fácilmente.

      Esta no es la única manera de crear su estructura. Algunas estructuras de archivos pueden aprovechar la división de código al especificar un directorio que se divida en varios paquetes. Otras estructuras de archivos se dividen por ruta y utilizan un directorio común para los componentes que se utilizan en todas las rutas.

      Por ahora, continúe con un enfoque menos complejo. Si surge la necesidad de tener otra estructura, siempre es más fácil pasar de lo sencillo a lo complejo. Comenzar con una estructura compleja antes de necesitarla, dificultará la refactorización.

      Ahora que creó y organizó un componente basado en clases, en el siguiente paso, creará un componente funcional.

      Paso 4: Crear un componente funcional

      En este paso, creará un componente funcional. Los componentes funcionales son los más comunes en el código de React contemporáneo. Estos componentes suelen ser más cortos y, a diferencia de los componentes basados en clases, pueden usar hooks de React, una nueva manera de gestionar estados y eventos.

      Un componente funcional es una función de JavaScript que devuelve cierto JSX. No requiere ampliar nada y no hay métodos especiales que memorizar.

      Para refactorizar <Instructions> como componente funcional, deberá cambiar la clase a una función y eliminar el método de representación de modo que solo quede la instrucción de retorno.

      Para hacerlo, primero, abra Instructions.js en un editor de texto.

      • nano src/components/Instructions/Instructions.js

      Cambie la declaración class a una declaración function:

      tutorial-03-component/src/components/Instructions/Instructions.js

      import React, { Component } from 'react';
      import './Instructions.css';
      import emoji from './emoji.svg'
      
      export default function Instructions() {
        render() {
          return(
            <div className="instructions">
              <img alt="laughing crying emoji" src={emoji} />
              <p>Click on an emoji to view the emoji short name.</p>
            </div>
          )
        }
      }
      

      Luego, elimine la importación de { Component }:

      tutorial-03-component/src/components/Instructions/Instructions.js

      import React from 'react';
      import './Instructions.css';
      import emoji from './emoji.svg'
      
      export default function Instructions() {
      
        render() {
          return(
            <div className="instructions">
              <img alt="laughing crying emoji" src={emoji} />
              <p>Click on an emoji to view the emoji short name.</p>
            </div>
          )
        }
      }
      

      Por último, elimine el método render(). En este punto, solo está devolviendo JSX.

      tutorial-03-component/src/components/Instructions/Instructions.js

      import React from 'react';
      import './Instructions.css';
      import emoji from './emoji.svg'
      
      export default function Instructions() {
        return(
          <div className="instructions">
              <img alt="laughing crying emoji" src={emoji} />
              <p>Click on an emoji to view the emoji short name.</p>
          </div>
        )
      }
      

      Guarde el archivo. El navegador se actualizará y verá su página como antes.

      Navegador con emoji

      También puede volver a escribir la función como función de flecha usando la devolución implícita. La principal diferencia es que pierde el cuerpo de la función. También deberá, primero, asignar la función a una variable y, luego, exportar esa variable:

      tutorial-03-component/src/components/Instructions/Instructions.js

      import React from 'react';
      import './Instructions.css';
      import emoji from './emoji.svg'
      
      const Instructions = () => (
        <div className="instructions">
          <img alt="laughing crying emoji" src={emoji} />
          <p>Click on an emoji to view the emoji short name.</p>
        </div>
      )
      
      export default Instructions;
      

      Los componentes funcionales simples y los componentes basados en clases son muy similares. Cuando tiene un componente sencillo que no almacena estados, lo mejor es usar un componente funcional. La diferencia real entre los dos tipos de componentes es la forma en que se almacenan su estado y sus propiedades de uso. Los componentes basados en clases utilizan métodos y propiedades para establecer el estado y suelen ser algo más largos. Los componentes funcionales utilizan hooks para almacenar el estado o gestionar cambios y suelen ser un poco más cortos.

      Conclusión

      Ahora, tiene una aplicación pequeña con piezas independientes. Creó componentes de los dos tipos principales: funcionales y basados en clases. Separó las partes de los componentes en directorios para poder mantener agrupadas porciones de código similares. También importó y reutilizó los componentes.

      Si comprende los componentes, puede comenzar a ver sus aplicaciones como piezas que puede desarmar y volver a armar. Los proyectos se vuelven modulares e intercambiables. La capacidad de ver aplicaciones completas como series de componentes es un paso importante para comprender React. Si desea acceder a más tutoriales de React, consulte nuestra página temática de React o regrese a la página de la serie Cómo programar con React.js.



      Source link