One place for hosting & domains

      Create

      How To Create Wrapper Components in React with Props


      The author selected Creative Commons to receive a donation as part of the Write for DOnations program.

      Introduction

      In this tutorial, you’ll create wrapper components with props using the React JavaScript library. Wrapper components are components that surround unknown components and provide a default structure to display the child components. This pattern is useful for creating user interface (UI) elements that are used repeatedly throughout a design, like modals, template pages, and information tiles.

      To create wrapper components, you’ll first learn to use the rest and spread operators to collect unused props to pass down to nested components. Then you’ll create a component that uses the built-in children component to wrap nested components in JSX as if they were HTML elements. Finally, you’ll pass components as props to create flexible wrappers that can embed custom JSX in multiple locations in a component.

      During the tutorial, you’ll build components to display a list of animal data in the form of cards. You’ll learn to split data and refactor components as you create flexible wrapping components. By the end of this tutorial, you’ll have a working application that will use advanced prop techniques to create reusable components that will scale and adapt as you application grows and changes.

      Note: The first step sets up a blank project on which you will build the tutorial exercise. If you already have a working project and want to go directly to working with props, start with Step 2.

      Prerequisites

      Step 1 — Creating an Empty Project

      In this step, you’ll create a new project using Create React App. Then you will delete the sample project and related files that are installed when you bootstrap the project. Finally, you will create a simple file structure to organize your components. This will give you a solid basis on which to build this tutorial’s wrapper application in the next step.

      To start, make a new project. In your command line, run the following script to install a fresh project using create-react-app:

      • npx create-react-app wrapper-tutorial

      After the project is finished, change into the directory:

      In a new terminal tab or window, start the project using the Create React App start script. The browser will auto-refresh on changes, so leave this script running while you work:

      You will get a running local server. If the project did not open in a browser window, you can open it with http://localhost:3000/. If you are running this from a remote server, the address will be http://your_domain:3000.

      Your browser will load with a simple React application included as part of Create React App:

      React template project

      You will be building a completely new set of custom components, so you’ll need to start by clearing out some boilerplate code so that you can have an empty project.

      To start, open src/App.js in a text editor. This is the root component that is injected into the page. All components will start from here. You can find more information about App.js at How To Set Up a React Project with Create React App.

      Open src/App.js with the following command:

      You will see a file like this:

      wrapper-tutorial/src/App.js

      import React from 'react';
      import logo from './logo.svg';
      import './App.css';
      
      function App() {
        return (
          <div className="App">
            <header className="App-header">
              <img src={logo} className="App-logo" alt="logo" />
              <p>
                Edit <code>src/App.js</code> and save to reload.
              </p>
              <a
                className="App-link"
                href="https://reactjs.org"
                target="_blank"
                rel="noopener noreferrer"
              >
                Learn React
              </a>
            </header>
          </div>
        );
      }
      
      export default App;
      

      Delete the line import logo from './logo.svg';. Then replace everything in the return statement to return a set of empty tags: <></>. This will give you a valid page that returns nothing. The final code will look like this:

      wrapper-tutorial/src/App.js

      
      import React from 'react';
      import './App.css';
      
      function App() {
        return <></>;
      }
      
      export default App;
      

      Save and exit the text editor.

      Finally, delete the logo. You won’t be using it in your application and you should remove unused files as you work. It will save you from confusion in the long run.

      In the terminal window type the following command:

      If you look at your browser, you will see a blank screen.

      blank screen in chrome

      Now that you have cleared out the sample Create React App project, create a simple file structure. This will help you keep your components isolated and independent.

      Create a directory called components in the src directory. This will hold all of you custom components.

      Each component will have its own directory to store the component file along with the styles, images if there are any, and tests.

      Create a directory for App:

      Move all of the App files into that directory. Use the wildcard, *, to select any files that start with App. regardless of file extension. Then use the mv command to put them into the new directory:

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

      Next, update the relative import path in index.js, which is the root component that bootstraps the whole process:

      The import statement needs to point to the App.js file in the App directory, so make the following highlighted change:

      wrapper-tutorial/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';
      
      ReactDOM.render(
        <React.StrictMode>
          <App />
        </React.StrictMode>,
        document.getElementById('root')
      );
      
      // If you want your app to work offline and load faster, you can change
      // unregister() to register() below. Note this comes with some pitfalls.
      // Learn more about service workers: https://bit.ly/CRA-PWA
      serviceWorker.unregister();
      

      Save and exit the file.

      Now that the project is set up, you can create your first component.

      Step 2 — Collecting Unused Props with ...props

      In this step, you’ll create a component to display a set of data about a group of animals. Your component will contain a second nested component to display some information visually. To connect the parent and nested component, you’ll use the rest and spread operators to pass unused props from the parent to the child without the parent needing to be aware of the names or types of the props.

      By the end of this step, you’ll have a parent component that can provide props to nested components without having to know what the props are. This will keep the parent component flexible, allowing you to update the child component without having to change the parent.

      Creating an AnimalCard Component

      To start, create a set of data for your animals. First, open a file containing the data set in the components/App directory:

      • nano src/components/App/data.js

      Add the following data:

      src/components/App/data.js

      
      export default [
        {
          name: 'Lion',
          scientificName: 'Panthero leo',
          size: 140,
          diet: ['meat']
        },
        {
          name: 'Gorilla',
          scientificName: 'Gorilla beringei',
          size: 205,
          diet: ['plants', 'insects']
        },
        {
          name: 'Zebra',
          scientificName: 'Equus quagga',
          size: 322,
          diet: ['plants'],
        }
      ]
      

      This list of animals is an array of objects that includes the animal’s name, scientific name, weight, and diet.

      Save and close the file.

      Next, create a directory for the AnimalCard component:

      • mkdir src/components/AnimalCard

      Open a new file in the directo:

      • nano src/components/AnimalCard/AnimalCard.js

      Now add a component that will take the name, diet, and size as a prop and display it:

      wrapper-tutorial/src/components/AnimalCard/AnimalCard.js

      import React from 'react';
      import PropTypes from 'prop-types';
      
      export default function AnimalCard({ diet, name, size }) {
        return(
          <div>
            <h3>{name}</h3>
            <div>{size}kg</div>
            <div>{diet.join(', ')}.</div>
          </div>
        )
      }
      
      AnimalCard.propTypes = {
        diet: PropTypes.arrayOf(PropTypes.string).isRequired,
        name: PropTypes.string.isRequired,
        size: PropTypes.number.isRequired,
      }
      

      Here you are destructuring the props in the parameter list for the AnimalCard function, then displaying the data in a div. The diet data is listed as a single string using the join() method. Each piece of data includes a corresponding PropType to make sure the data type is correct.

      Save and close the file.

      Now that you have your component and your data, you need to combine them together. To do that, import the component and the data into the root component of your project: App.js.

      First, open the component:

      • nano src/components/App/App.js

      From there, you can loop over the data and return a new AnimalCard with the relevant props. Add the highlighted lines to App.js:

      wrapper-tutorial/src/components/App/App.js

      import React from 'react';
      import './App.css';
      
      import animals from './data';
      import AnimalCard from '../AnimalCard/AnimalCard';
      
      function App() {
        return (
          <div className="wrapper">
            {animals.map(animal =>
              <AnimalCard
                diet={animal.diet}
                key={animal.name}
                name={animal.name}
                size={animal.size}
              />
            )}
          </div>
        );
      }
      
      export default App;
      

      Save and close the file.

      As you work on more complex projects, your data will come from more varied places, such as APIs, localStorage, or static files. But the process for using each of these will be similar: assign the data to a variable and loop over the data. In this case, the data is from a static file, so you are importing directly to a variable.

      In this code, you use the .map() method to iterate over animals and display the props. Notice that you do not have to use every piece of data. You are not explicitly passing the scientificName property, for example. You are also adding a separate key prop that React will use to keep track of the mapped data. Finally, you are wrapping the code with a div with a className of wrapper that you’ll use to add some styling.

      To add this styling, open App.css:

      • nano src/components/App/App.css

      Remove the boilerplate styling and add flex properties to a class called wrapper:

      prop-tutorial/src/components/App/App.js

      .wrapper {
          display: flex;
          flex-wrap: wrap;
          justify-content: space-between;
          padding: 20px;
      }
      

      This will use flexbox layout to organize the data so it will line up. padding gives some space in the browser window, and justify-content spreads out the extra space between elements.

      Save and exit the file. When you do, the browser will refresh and you’ll see some data spaced out.

      Browser with data spaced out

      Creating a Details Component

      You now have a simple component that displays the data. But let’s say you wanted to give the diet data a little flair by converting the text to an emoji. You can do this by converting the data in your component.

      React is designed to be flexible, so when you are thinking about how to convert data, you have a few different options:

      • You can create a function inside the component that converts the text to an emoji.
      • You can create a function and store it in a file outside the component so that you can reuse the logic across different components.
      • You can create a separate component that converts the text to an emoji.

      Each approach is fine when applied to the right use case, and you’ll find yourself switching between them as you build an application. To avoid premature abstraction and complexity, you should use the first option to start. If you find yourself wanting to reuse logic, you can pull the function out separately from the component. The third option is best if you want to have a reusable piece that includes the logic and the markup, or that you want to isolate to use across the application.

      In this case, we’ll make a new component, since we will want to add more data later and we are combining markup with conversion logic.

      The new component will be called AnimalDetails. To make it, create a new directory:

      • mkdir src/components/AnimalDetails

      Next, open AnimalDetails.js in your text editor:

      • nano src/components/AnimalDetails/AnimalDetails.js

      Inside the file, make a small component that displays the diet as an emoji:

      wrapper-tutorial/src/components/AnimalDetails/AnimalDetails.js

      import React from 'react';
      import PropTypes from 'prop-types';
      import './AnimalDetails.css';
      
      function convertFood(food) {
        switch(food) {
          case 'insects':
            return '🐜';
          case 'meat':
            return '🍖';
          case 'plants':
          default:
            return '🌱';
        }
      }
      
      export default function AnimalDetails({ diet }) {
        return(
          <div className="details">
            <h4>Details:</h4>
            <div>
              Diet: {diet.map(food => convertFood(food)).join(' ')}
            </div>
          </div>
        )
      }
      
      AnimalDetails.propTypes = {
        diet: PropTypes.arrayOf(PropTypes.string).isRequired,
      }
      

      The AnimalDetails.propTypes object sets up the function to take a prop of diet that is an array of strings. Then inside the component, the code loops over the diet and converts the string to an emoji using the switch statement.

      Save and close the file.

      You are also importing some CSS, so let’s add that now.

      Open AnimalDetails.css:

      • nano src/components/AnimalDetails/AnimalDetails.css

      Add some CSS to give the element a border and margin to separate the details from the rest of the component:

      wrapper-tutorial/src/components/AnimalDetails/AnimalDetails.css

      .details {
          border-top: gray solid 1px;
          margin: 20px 0;
      }
      

      We use .details to match the rule to elements with a className of details.

      Save and close the file.

      Now that you have a new custom component, you can add it to your AnimalCard component. Open AnimalCard.js:

      • nano src/components/AnimalCard/AnimalCard.js

      Replace the diet.join statement with the new AnimalDetails component and pass diet as a prop by adding the highlighted lines:

      wrapper-tutorial/src/components/AnimalCard/AnimalCard.js

      import React from 'react';
      import PropTypes from 'prop-types';
      import AnimalDetails from '../AnimalDetails/AnimalDetails';
      
      export default function AnimalCard({ diet, name, size }) {
        return(
          <div>
            <h3>{name}</h3>
            <div>{size}kg</div>
            <AnimalDetails
              diet={diet}
            />
          </div>
        )
      }
      
      AnimalCard.propTypes = {
        diet: PropTypes.arrayOf(PropTypes.string).isRequired,
        name: PropTypes.string.isRequired,
        size: PropTypes.number.isRequired,
      }
      

      Save the file and you’ll see the new details in the browser.

      Browser with details

      Passing Details Through a Component with ...props

      The components are working well together, but there’s a slight inefficiency in AnimalCard. You are explicitly pulling diet out from the props argument, but you aren’t using the data. Instead, you are passing it through to the component. There’s nothing inherently wrong about this—in fact, it’s often better to err on the side of too much communication. But in doing this, you make your code more difficult to maintain. Whenever you want to pass new data to AnimalDetails, you need to update three places: App, where you pass the props, AnimalDetails, which consumes the prop, and AnimalCard, which is the go-between.

      A better way is to gather any unused props inside AnimalCard and then pass those directly to AnimalDetails. This gives you the chance to make changes to AnimalDetails without changing AnimalCard. In effect, AnimalCard doesn’t need to know anything about the props or the PropTypes that are going into AnimalDetails.

      To do that, you’ll use the object rest operator. This operator collects any items that are not pulled out during destructuring and saves them into a new object.

      Here’s a simple example:

      const dog = {
          name: 'dog',
          diet: ['meat']
      }
      
      const { name, ...props  } = dog;
      

      In this case, the variable name will be 'dog' and the variable props will be { diet: ['meat']}.

      Up till now, you’ve passed all props as if they were HTML attributes, but you can also use objects to send props. To use an object as a prop, you need to use the spread operator—...props—surrounded with curly braces. This will change each key-value pair into a prop.

      Open AnimalCard.js:

      • nano src/components/AnimalCard/AnimalCard.js

      Inside, remove diet from the destructured object and instead collect the rest of the props into a variable called props. Then pass those props directly to AnimalDetails:

      wrapper-tutorial/src/components/AnimalCard/AnimalCard.js

      import React from 'react';
      import PropTypes from 'prop-types';
      import AnimalDetails from '../AnimalDetails/AnimalDetails';
      
      export default function AnimalCard({ name, size, ...props }) {
        return(
          <div>
            <h3>{name}</h3>
            <div>{size}kg</div>
            <AnimalDetails
              {...props}
            />
          </div>
        )
      }
      
      AnimalCard.propTypes = {
        name: PropTypes.string.isRequired,
        size: PropTypes.number.isRequired,
      }
      

      Notice that you can remove the diet PropType since you are not using the prop in this component.

      In this case, you are only passing one prop to AnimalDetails. In cases where you have multiple props, the order will matter. A later prop will overwrite earlier props, so if you have a prop you want to take priority, make sure it is last. This can cause some confusion if your props object has a property that is also a named value.

      Save and close the file. The browser will refresh and everything will look the same:

      Browser with details

      To see how the ...props object adds flexibility, let’s pass the scientificName to AnimalDetails via the AnimalCard component.

      First, open App.js:

      • nano src/components/App/App.js

      Then pass the scientificName as a prop:

      wrapper-tutorial/src/components/App/App.js

      import React from 'react';
      import './App.css';
      
      import animals from './data';
      import AnimalCard from '../AnimalCard/AnimalCard';
      
      function App() {
        return (
          <div className="wrapper">
            {animals.map(animal =>
              <AnimalCard
                diet={animal.diet}
                key={animal.name}
                name={animal.name}
                size={animal.size}
                scientificName={animal.scientificName}
              />
            )}
          </div>
        );
      }
      
      export default App;
      

      Save and close the file.

      Skip over AnimalCard; you won’t need to make any changes there. Then open AnimalDetails so you can consume the new prop:

      • nano src/components/AnimalDetails/AnimalDetails.js

      The new prop will be a string, which you’ll add to the details list along with a line declaring the PropType:

      wrapper-tutorial/src/components/AnimalDetails/AnimalDetails.js

      import React from 'react';
      ...
      export default function AnimalDetails({ diet, scientificName }) {
        return(
          <div className="details">
            <h4>Details:</h4>
            <div>
              Scientific Name: {scientificName}.
            </div>
            <div>
              Diet: {diet.map(food => convertFood(food)).join(' ')}
            </div>
          </div>
        )
      }
      
      AnimalDetails.propTypes = {
        diet: PropTypes.arrayOf(PropTypes.string).isRequired,
        scientificName: PropTypes.string.isRequired,
      }
      

      Save and close the file. When you do, the browser will refresh and you’ll see the new details without any changes to the AnimalCard component:

      Browser with scientific name

      In this step, you learned how to create flexible parent props that can take unknown props and pass them into nested components with the spread operator. This is a common pattern that will give you the flexibility you need to create components with focused responsibilities. In the next step, you’ll create components that can take unknown components as a prop using the built in children prop.

      Step 3 — Creating Wrapper Components with children

      In this step, you’ll create a wrapper component that can take an unknown group of components as a prop. This will give you the ability to nest components like standard HTML, and it will give you a pattern for creating reusable wrappers that will let you make a variety of components that need a common design but a flexible interior.

      React gives you a built-in prop called children that collects any children components. Using this makes creating wrapper components intuitivie and readable.

      To start, make a new component called Card. This will be a wrapper component to create a standard style for any new card components.

      Create a new directory:

      • mkdir src/components/Card

      Then open the Card component in your text editor:

      • nano src/components/Card/Card.js

      Create a component that takes children and title as props and wraps them in a div by adding the following code:

      wrapper-tutorial/src/components/Card/Card.js

      import React from 'react';
      import PropTypes from 'prop-types';
      import './Card.css';
      
      export default function Card({ children, title }) {
        return(
          <div className="card">
            <div className="card-details">
              <h2>{title}</h2>
            </div>
            {children}
          </div>
        )
      }
      
      Card.propTypes = {
        children: PropTypes.oneOfType([
          PropTypes.arrayOf(PropTypes.element), 
          PropTypes.element.isRequired
        ]),
        title: PropTypes.string.isRequired,
      }
      

      The PropTypes for the children are new. The children prop can either be a JSX element or an array of JSX elements. The title is a string.

      Save and close the file.

      Next, add some styling. Open Card.css:

      • nano src/components/Card/Card.css

      Your card will have a border and a line under the details.

      wrapper-tutorial/src/components/Card/Card.css

      .card {
          border: black solid 1px;
          margin: 10px;
          padding: 10px;
          width: 200px;
      }
      
      .card-details {
          border-bottom: gray solid 1px;
          margin-bottom: 20px;
      }
      

      Save and close the file. Now that you have your component you need to use it. You could wrap each AnimalCard with the Card component in App.js, but since the name AnimalCard implies it is already a Card, it would be better to use the Card component inside of AnimalCard.

      Open up AnimalCard:

      • nano src/components/AnimalCard/AnimalCard.js

      Unlike other props, you don’t pass children explicitly. Instead, you include the JSX as if they were HTML child elements. In other words, you just nest them inside of the element, like the following:

      wrapper-tutorial/src/components/AnimalCard/AnimalCard.js

      import React from 'react';
      import PropTypes from 'prop-types';
      import Card from '../Card/Card';
      import AnimalDetails from '../AnimalDetails/AnimalDetails';
      
      export default function AnimalCard({ name, size, ...props }) {
        return(
          <Card title="Animal">
            <h3>{name}</h3>
            <div>{size}kg</div>
            <AnimalDetails
              {...props}
            />
          </Card>
        )
      }
      
      AnimalCard.propTypes = {
        name: PropTypes.string.isRequired,
        size: PropTypes.number.isRequired,
      }
      

      Unlike a React component, you do not need to have a single root element as a child. That’s why the PropType for Card specified it could be an array of elements or a single element. In addition to passing the children as nested components, you are giving the card a title of Animal.

      Save and close the file. When you do, the browser will refresh and you’ll see the updated card component.

      Browser with cards

      Now you have a reusable Card component that can take any number of nested children. The primary advantage of this is that you can reuse the Card with any arbitrary component. If you wanted to make a Plant card, you could do that by wrapping the plant information with the Card component. It doesn’t even need to relate at all: If you wanted to reuse the Card component in a completely different applications that lists things like music or account data, you could do that, too. The Card component doesn’t care what the children are; you are just reusing the wrapper element, which in this case is the styled border and title.

      The downside to using children is that you can only have one instance of the child prop. Occasionally, you’ll want a component to have custom JSX in multiple places. Fortunately, you can do that by passing JSX and React components as props, which we will cover in the next step.

      Step 4 — Passing Components as Props

      In this step, you’ll modify your Card component to take other components as props. This will give your component maximum flexibility to display unknown components or JSX in multiple locations throughout the page. Unlike children, which you can only use once, you can have as many components as props, giving your wrapper component the ability to adapt to a variety of needs while maintaining a standard look and structure.

      By the end of this step, you’ll have a component that can wrap children components and also display other components in the card. This pattern will give you flexibility when you need to create components that need information that is more complex than simple strings and integers.

      Let’s modify the Card component to take an arbitrary React element called details.

      First, open the Card component:

      • nano src/components/Card/Card.js

      Next, add a new prop called details and place it below the <h2> element:

      wrapper-tutorial/src/components/Card/Card.js

      import React from 'react';
      import PropTypes from 'prop-types';
      import './Card.css';
      
      export default function Card({ children, details, title }) {
        return(
          <div className="card">
            <div className="card-details">
              <h2>{title}</h2>
              {details}
            </div>
            {children}
          </div>
        )
      }
      
      Card.propTypes = {
        children: PropTypes.oneOfType([
          PropTypes.arrayOf(PropTypes.element), 
          PropTypes.element.isRequired
        ]),
        details: PropTypes.element,
        title: PropTypes.string.isRequired,
      }
      
      Card.defaultProps = {
        details: null,
      }
      

      This prop will have the same type as children, but it should be optional. To make it optional, you add a default value of null. In this case, if a user passes no details, the component will still be valid and will not display anything extra.

      Save and close the file. The page will refresh and you’ll see the same image as before:

      Browser with cards

      Now add some details to the AnimalCard. First, open AnimalCard.

      • nano src/components/AnimalCard/AnimalCard.js

      Since the Card component is already using children, you’ll need to pass the new JSX component as a prop. Since these are all mammals, add that to the card, but wrap it in <em> tags to make it italic.

      wrapper-tutorial/src/components/AnimalCard/AnimalCard.js

      import React from 'react';
      ...
      
      export default function AnimalCard({ name, size, ...props }) {
        return(
          <Card title="Animal" details={<em>Mammal</em>}>
            <h3>{name}</h3>
            <div>{size}kg</div>
            <AnimalDetails
              {...props}
            />
          </Card>
        )
      }
      ...
      

      Save the file. When you do, the browser will refresh and you’ll see the update, including the phrase Mammal.

      Browser with card and details

      This prop is already powerful because it can take JSX of any size. In this example, you added only a single element, but you could pass as much JSX as you wanted. It also doesn’t have to be JSX. If you have a complicated markup for example, you wouldn’t want to pass it directly in the prop; this would be difficult to read. Instead, you could create a separate component and then pass the component as a prop.

      To see this at work, pass AnimalDetails to the details prop:

      wrapper-tutorial/src/components/AnimalCard/AnimalCard.js

      import React from 'react';
      ...
      
      export default function AnimalCard({ name, size, ...props }) {
        return(
          <Card
            title="Animal"
            details={
              <AnimalDetails
                {...props}
              />
            }
          >
            <h3>{name}</h3>
            <div>{size}kg</div>
          </Card>
        )
      }
      ...
      

      AnimalDetails is more complicated and has a number of lines of markup. If you were to add it directly to details, it would increase the prop substantially and make it difficult to read.

      Save and close the file. When you do, the browser will refresh and the details will appear at the top of the card.

      Card with details at the top

      Now you have a Card component that can take custom JSX and place it in multiple spots. You are not restricted to a single prop; you can pass elements to as many props as you want. This gives you the ability to create flexible wrapping components that can give other developers the opportunity to customize a component while retaining its overall style and functionality.

      Passing a component as a prop isn’t perfect. It’s a little more difficult to read and isn’t as clear as passing children, but they are just as flexible and you can use as many of them as you want in a component. You should use children first, but don’t hesitate to fall back to props if that is not enough.

      In this step, you learned how to pass JSX and React components as props to another component. This will give your component the flexibility to handle many situations where a wrapper component may need multiple props to handle JSX or components.

      Conclusion

      You have created a variety of wrapping components that can display data flexibly while keeping a predictable look and structure. You created components that can collect and pass unknown props to nested components. You also used the built-in children prop to create wrapper components that can handle an arbitrary number of nested elements. Finally, you created a component that can take JSX or React components as a prop so that your wrapper component can handle multiple instances of different customizations.

      Wrapper components give you the ability to adapt to unknown circumstances while also maximizing code reuse and consistency. This pattern is useful for creating basic UI elements that you will reuse throughout an application including: buttons, alerts, modals, slide shows, and more. You’ll find yourself returning to it many times.

      If you would like to look at more React tutorials, check out our React Topic page, or return to the How To Code in React.js series page.



      Source link

      How To Create a Minecraft Server on Ubuntu 18.04


      The author selected the Tech Education Fund to receive a donation as part of the Write for DOnations program.

      Introduction

      Minecraft is a popular sandbox video game. Originally released in 2009, it allows players to build, explore, craft, and survive in a block 3D generated world. As of late 2019, it was the second best-selling video game of all time. In this tutorial, you will create your own Minecraft server so that you and your friends can play together. Specifically, you will install the necessary software packages to run Minecraft, configure the server to run, and then deploy the game.

      Alternately, you can explore DigitalOcean’s One-Click Minecraft: Java Edition Server as another installation path.

      This tutorial uses the Java version of Minecraft. If you purchased your version of Minecraft through the Microsoft App Store, you will be unable to connect to this server. Most versions of Minecraft purchased on gaming consoles such as the PlayStation 4, Xbox One, or Nintendo Switch are also the Microsoft version of Minecraft. These consoles are also unable to connect to the server built in this tutorial. You can obtain the Java version of Minecraft here.

      Prerequisites

      In order to follow this guide, you’ll need:

      Step 1 — Installing the Necessary Software Packages and Configure the Firewall

      With your server initialized, your first step is to install Java; you’ll need it to run Minecraft.

      Update the package index for the APT package manager:

      Next, install the OpenJDK version 8 of Java, specifically the headless JRE. This is a minimal version of Java that removes the support for GUI applications. This makes it ideal for running Java applications on a server:

      • sudo apt install openjdk-8-jre-headless

      You also need to use a software called screen to create detachable server sessions. screen allows you to create a terminal session and detach from it, leaving the process started on it running. This is important because if you were to start your server and then close your terminal, this would kill the session and stop your server. Install screen now:

      Now that you have the packages installed we need to enable the firewall to allow traffic to come in to our Minecraft server. In the initial server setup that you performed you only allowed traffic from SSH. Now you need to allow for traffic to come in via port 25565, which is the default port that Minecraft uses to allow connections. Add the necessary firewall rule by running the following command:

      Now that you have Java installed and your firewall properly configured, you will download the Minecraft server from the Minecraft website.

      Step 2 — Downloading the Latest Version of Minecraft

      Now you need to download the current version of the Minecraft server. You can do this by navigating to Minecraft’s Website and copying the link that says Download minecraft_server.X.X.X.jar, where the X’s are the latest version of the server.

      You can now use wget and the copied link to download the server:

      • wget https://launcher.mojang.com/v1/objects/bb2b6b1aefcd70dfd1892149ac3a215f6c636b07/server.jar

      If you intend to upgrade your Minecraft server, or if you want to run different versions of Minecraft, rename the downloaded server.jar to minecraft_server_1.15.2.jar, matching the highlighted version numbers to whatever version you just downloaded:

      • mv server.jar minecraft_server_1.15.2.jar

      If you want to download an older version of Minecraft, you can find them archived at mcversions.net. But this tutorial will focus on the current latest release. Now that you have your download let’s start configuring your Minecraft server.

      Step 3 — Configuring and Running the Minecraft Server

      Now that you have the Minecraft jar downloaded, you are ready to run it.

      First, start a screen session by running the screen command:

      Once you have read the banner that has appeared, press the SPACE bar. screen will present you with a terminal session like normal. This session is now detachable, which means that you’ll be able to start a command here and leave it running.

      You can now perform your initial configuration. Do not be alarmed when this next command throws an error. Minecraft has designed its installation this way so that users must first consent to the company’s licensing agreement. You will do this next:

      • java -Xms1024M -Xmx1024M -jar minecraft_server_1.15.2.jar nogui

      Before examining this command’s output, let’s take a closer look at all these command-line arguments, which are tuning your server:

      • Xms1024M – This configures the server to start running with 1024MB or 1GB of RAM running. You can raise this limit if you want your server to start with more RAM. Both M for megabytes and G for gigabytes are supported options. For example: Xms2G will start the server with 2 gigabytes of RAM.

      • Xmx1024M – This configures the server to use, at most, 1024M of RAM. You can raise this limit if you want your server to run at a larger size, allow for more players, or if you feel that your server is running slowly.

      • jar – This flag specifies which server jar file to run.

      • nogui – This tells the server not to launch a GUI since this is a server, and you don’t have a graphical user interface.

      The first time you run this command, which normally starts your server, it will instead generate the following error:

      Output

      [22:05:31] [22:05:31] [main/ERROR]: Failed to load properties from file: server.properties [22:05:31] [main/WARN]: Failed to load eula.txt [22:05:31] [main/INFO]: You need to agree to the EULA in order to run the server. Go to eula.txt for more info.

      These errors were generated because the server could not find two necessary files required for execution: the EULA (End User License Agreement), found in eula.txt, and the configuration file server.properties. Fortunately, since the server was unable to find these files, it created them in your current working directory.

      First, open eula.txt in nano or your favorite text editor:

      Inside this file, you will see a link to the Minecraft EULA. Copy the URL:

      ~/eula.txt

      #By changing the setting below to TRUE you are indicating your agreement to our EULA (https://account.mojang.com/documents/minecraft_eula).
      #Tue Mar 24 22:05:31 UTC 2020
      eula=false
      

      Open the URL in your web browser and read the agreement. Then return to your text editor and find the last line in eula.txt. Here, change eula=false to eula=true. Now save and close the file.

      Now that you’ve accepted the EULA, it is time to configure the server to your specifications.

      In your current working directory, you will also find the newly created server.properties file. This file contains all of the configuration options for your Minecraft server. You can find a detailed list of all server properties on the Official Minecraft Wiki. You will modify this file with your preferred settings before starting your server. This tutorial will cover the fundamental properties:

      Your file will appear like this:

      ~/server.properties

      #Minecraft server properties
      #Thu Apr 30 23:42:29 UTC 2020
      spawn-protection=16
      max-tick-time=60000
      query.port=25565
      generator-settings=
      force-gamemode=false
      allow-nether=true
      enforce-whitelist=false
      gamemode=survival
      broadcast-console-to-ops=true
      enable-query=false
      player-idle-timeout=0
      difficulty=easy
      spawn-monsters=true
      broadcast-rcon-to-ops=true
      op-permission-level=4
      pvp=true
      snooper-enabled=true
      level-type=default
      hardcore=false
      enable-command-block=false
      max-players=20
      network-compression-threshold=256
      resource-pack-sha1=
      max-world-size=29999984
      function-permission-level=2
      rcon.port=25575
      server-port=25565
      server-ip=
      spawn-npcs=true
      allow-flight=false
      level-name=world
      view-distance=10
      resource-pack=
      spawn-animals=true
      white-list=false
      rcon.password=
      generate-structures=true
      online-mode=true
      max-build-height=256
      level-seed=
      prevent-proxy-connections=false
      use-native-transport=true
      motd=A Minecraft Server
      enable-rcon=false
      

      Let’s take a closer look at some of the most important properties in this list:

      • difficulty (default easy) – This sets the difficulty of the game, such as how much damage is dealt and how the elements affect your player. The options are peaceful, easy, normal, and hard.

      • gamemode (default survival) – This sets the gameplay mode. The options are survival, creative,adventure, and spectator.

      • level-name (default world) – This sets the name of your server that will appear in the client. Characters such as the apostrophe may need to be escaped with a backslash.

      • motd (default A Minecraft Server) – The message that is displayed in the server list of the Minecraft client.

      • pvp (default true) – Enables Player versus Player combat. If set to true, players will be able to engage in combat and damage each other.

      Once you have set the options that you want, save and close the file.

      Now that you have changed EULA to true and configured your settings, you can successfully start your server.

      Like last time, let’s start your server with 1024M of RAM. Only now, let’s also grant Minecraft the ability to use up to 4G of RAM if it needs it. Remember, you are welcome to adjust this number to fit your server limitations or user needs:

      • java -Xms1024M -Xmx4G -jar minecraft_server_1.15.2.jar nogui

      Give the initialization a few moments. Soon your new Minecraft server will start producing an output similar to this:

      Output

      [21:08:14] [Server thread/INFO]: Starting minecraft server version 1.15.2 [21:08:14] [Server thread/INFO]: Loading properties [21:08:14] [Server thread/INFO]: Default game type: SURVIVAL [21:08:14] [Server thread/INFO]: Generating keypair [21:08:15] [Server thread/INFO]: Starting minecraft server on *:25565

      Once the server is up and running, you will see the following output:

      Output

      [21:15:37] [Server thread/INFO]: Done (30.762s)! For help, type "help"

      Your server is now running, and you have been dropped into the server administrator control panel. Now type help:

      An output like this will appear:

      Output

      [21:15:37] [Server thread/INFO]: /advancement (grant|revoke) [21:15:37] [Server thread/INFO]: /ban <targets> [<reason>] [21:15:37] [Server thread/INFO]: /ban-ip <target> [<reason>] [21:15:37] [Server thread/INFO]: /banlist [ips|players] ...

      From this terminal you can execute administrator commands and control your Minecraft server. Now let’s use screen to keep your new server running, even after you log out. Then you can connect to your Minecraft client and start a new game.

      Step 4 — Keeping the Server Running

      Now that you have your server up, you want it to remain running even after you disconnect from your SSH session. Since you used screen earlier, you can detach from this session by pressing Ctrl + A + D. Now you’re back in your original shell.

      Run this command to see all of your screen sessions:

      You’ll get an output with the ID of your session, which you’ll need to resume that session:

      Output

      There is a screen on: 26653.pts-0.minecraft (03/25/20 21:18:31) (Detached) 1 Socket in /run/screen/S-root.

      To resume your session, pass the -r flag to the screen command and then enter your session ID:

      When you are ready to log out of your server, be sure to detach from the session with Ctrl + A + D and then log out.

      Step 5 — Connecting to Your Server from the Minecraft Client

      Now that your server is up and running, let’s connect to it through the Minecraft client. Then you can play!

      Launch your copy of Minecraft Java Edition and select Multiplayer in the menu.

      Select Multiplayer in the menu

      Next, you will need to add a server to connect to, so click on the Add Server button.

      Click the Add Server button

      In the Edit Server Info screen that shows up, give your server a name and type in the IP address of your server. This is the same IP address that you used to connect through SSH.

      Name your server and type in the IP address

      Once you have entered your server name and IP address, you’ll be taken back to the Multiplayer screen where your server will now be listed.

      Select your server and click Join Server

      From now on, your server will always appear in this list. Select it and click Join Server.

      Enjoy the game!

      You are in your server and ready to play!

      Conclusion

      You now have a Minecraft server running on Ubuntu 18.04 for you and all of your friends to play on! Have fun exploring, crafting, and surviving in a crude 3D world. And remember: watch out for griefers.



      Source link

      Cómo configurar un proyecto de React con Create React App


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

      Introducción

      React es un marco de trabajo de JavaScript popular para la creación de aplicaciones de front-end. Creado originalmente por Facebook, ganó popularidad al permitir que los desarrolladores creen aplicaciones rápidas usando un paradigma de programación intuitivo que vincula JavaScript con una sintaxis similar a HTML conocida como JSX.

      Iniciar un nuevo proyecto de React solía ser un proceso complicado de varios pasos que implicaba la configuración de un sistema de compilación, un transpilador de código para convertir la sintaxis moderna en código que todos los navegadores pudieran leer y una estructura de directorios básica.  Pero, ahora, Create React App incluye todos los paquetes de JavaScript que necesita para ejecutar un proyecto de React, como transpilación de código, linting básico, pruebas y sistemas de compilación. También incluye un servidor con recarga directa que actualiza su página a medida que realiza cambios de código. Por último, creará una estructura para sus directorios y componentes para poder comenzar a codificar en minutos.

      En otras palabras, no tiene que preocuparse por configurar un sistema de compilación como Webpack. No necesita configurar Babel para que convierta a otro lenguaje su código de modo que se pueda utilizar en todos los navegadores. No tiene que preocuparse por la mayoría de los sistemas complejos de desarrollo de front-end moderno. Puede comenzar a escribir código de React con una preparación mínima.

      Al final de este tutorial, tendrá una aplicación de React en ejecución que puede usar como base para cualquier aplicación futura. Hará los primeros cambios en el código de React, actualizará los estilos y ejecutará una compilación para crear una versión totalmente reducida de su aplicación. También usará un servidor con recarga directa para obtener comentarios al instante y analizará en profundidad las partes que componen un proyecto de React. Por último, comenzará a escribir componentes personalizados y a crear una estructura que pueda evolucionar y adaptarse a su proyecto.

      Requisitos previos

      Para seguir este tutorial, necesitará lo siguiente:

      Paso 1: Crear un nuevo proyecto con Create React App

      En este paso, creará una nueva aplicación usando el administrador de paquetes npm para ejecutar una secuencia de comandos remota. La secuencia de comandos copiará los archivos necesarios en un directorio nuevo e instalará todas las dependencias.

      Cuando instaló Node, también instaló una aplicación de administración de paquetes llamada npm. La aplicación npm instalará paquetes de JavaScript en su proyecto y también llevará un registro de los detalles de este.  Si desea obtener más información sobre npm, consulte nuestro tutorial Cómo usar módulos de Node.js con npm y package.json.

      La aplicación npm también incluye una herramienta denominada npx que ejecuta los paquetes ejecutables. Esto significa que ejecutará el código de Create React App sin descargar el proyecto primero.

      El paquete ejecutable ejecutará la instalación de create-react-app en el directorio que especifique. Comenzará por crear un nuevo proyecto en un directorio que, en este tutorial, recibirá el nombre digital-ocean-tutorial. Una vez más, no es necesario que este directorio exista de antemano; el paquete ejecutable lo creará. La secuencia de comandos también ejecutará npm install dentro del directorio del proyecto, que descargará cualquier dependencia adicional.

      Para instalar el proyecto de base, ejecute el siguiente comando:

      • npx create-react-app digital-ocean-tutorial

      Este comando iniciará un proceso de compilación que descargará el código básico junto con varias dependencias.

      Cuando la secuencia de comandos finalice, verá un mensaje de operación correcta que indica lo siguiente:

      Output

      ... Success! Created digital-ocean-tutorial at your_file_path/digital-ocean-tutorial Inside that directory, you can run several commands: npm start Starts the development server. npm run build Bundles the app into static files for production. npm test Starts the test runner. npm run eject Removes this tool and copies build dependencies, configuration files and scripts into the app directory. If you do this, you can’t go back! We suggest that you begin by typing: cd digital-ocean-tutorial npm start Happy hacking!

      your_file_path será su ruta actual. Si es usuario de macOS, será algo similar a /Users/your_username; si está usando Ubuntu, indicara algo como /home/your_username;

      También verá una lista de comandos npm que le permitirán ejecutar, compilar, iniciar y probar su aplicación. Los veremos en detalle en la siguiente sección.

      Nota: Hay otro administrador de paquetes para JavaScript llamado yarn. Facebook lo admite y hace muchas de las mismas cosas que npm. Originalmente, yarn proporcionó funcionalidades nuevas, como archivos de bloqueo, pero ahora estas también se implementan en npm. yarn también incluye algunas características adicionales, como el almacenamiento en caché sin conexión. Puede encontrar más información sobre las diferencias en la documentación de yarn.

      Si instaló yarn en su sistema anteriormente, verá una lista de comandos yarn, como yarn start, que tienen el mismo funcionamiento que los comandos npm. Puede ejecutar comandos npm incluso si tiene yarn instalado. Si prefiere yarn, simplemente reemplace npm por yarn en todos los comandos futuros. Los resultados serán los mismos.

      Ahora, su proyecto está configurado en un directorio nuevo. Pase al directorio nuevo:

      • cd digital-ocean-tutorial

      Ahora, se encuentra en el directorio root de su proyecto. En este punto, creó un proyecto nuevo y añadió todas las dependencias. Pero no hizo nada para ejecutarlo. En la siguiente sección, ejecutará secuencias de comandos personalizadas para compilar y probar el proyecto.

      Paso 2: Usar react-scripts

      En este paso, aprenderá los distintos react-scripts que se instalan con el repositorio. Primero, ejecutará la secuencia de comandos test para ejecutar el código de prueba. Luego, ejecutará la secuencia de comandos build para crear una versión reducida. Por último, analizará la forma en que la secuencia de comandos eject puede permitirle controlar la personalización por completo.

      Ahora que se encuentra en el directorio del proyecto, obsérvelo. Puede abrir todo el directorio en su editor de texto o, si está en la terminal, puede enumerar los archivos con el siguiente comando:

      El indicador -a garantiza que el resultado también incluya archivos ocultos.

      De cualquier manera, verá una estructura como la siguiente:

      Output

      node_modules/ public/ src/ .gitignore README.md package-lock.json package.json

      Veamos la explicación de cada uno de estos componentes:

      • node_modules/ contiene todas las bibliotecas de JavaScript externas que utiliza la aplicación. Rara vez necesitará abrirlo.

      • El directorio public/ contiene algunos archivos de imagen, HTML y JSON. Estos son los directorios root de su proyecto. Los analizaremos en más detalle en el paso 4.

      • El directorio src/ contiene el código JavaScript React de su proyecto. La mayor parte del trabajo que haga se encontrará en ese directorio. Veremos este directorio en detalle en el paso 5.

      • El archivo .gitignore contiene algunos directorios y archivos predeterminados que git, su control de código fuente, ignorará, como el directorio node_modules. Los elementos ignorados suelen ser directorios o archivos de registro de mayor tamaño que no necesitará en el control de código fuente. También incluirá algunos directorios que creará con ciertas secuencias de comandos de React.

      • README.md es un archivo markdown que contiene mucha información útil sobre Create React App, como, por ejemplo, un resumen de los comandos y enlaces a la configuración avanzada. Por ahora, es mejor dejar el archivo README.md como lo ve. A medida que vaya avanzando con su proyecto, sustituirá la información predeterminada por información más detallada sobre él.

      El administrador de paquetes usa los dos últimos archivos. Cuando ejecutó el comando inicial npx, no solo creó el proyecto de base, también instaló las dependencias adicionales. Al instalar las dependencias, creó un archivo package-lock.json. El administrador de paquetes npm usa este archivo para garantizar que los paquetes coincidan con versiones exactas. De esta manera, si otra persona instala su proyecto, puede asegurarse de que tendrá dependencias idénticas. Debido a que este archivo se crea de forma automática, rara vez editará este archivo directamente.

      El último archivo es package.json. Contiene metadatos sobre su proyecto, como el título, el número de versión y las dependencias. También contiene secuencias de comandos que puede usar para ejecutar su proyecto.

      Abra el archivo package.json en el editor de texto que prefiera:

      Al abrir el archivo, verá un objeto JSON que contiene todos los metadatos. Si observa el objeto scripts, notará que contiene cuatro secuencias de comandos diferentes: start, build, test y eject.

      Estas secuencias de comandos se enumeran en orden de importancia. La primera comienza el entorno de desarrollo local; la veremos en el siguiente paso. La segunda compilará su proyecto. Verá esto en detalle en el paso 4, pero es bueno ejecutarla ahora para ver qué sucede.

      La secuencia de comandos build

      Para ejecutar cualquier secuencia de comandos npm, simplemente debe escribir npm run script_name en su terminal. Hay algunas secuencias de comandos especiales en las que se puede omitir la parte de run, pero siempre se puede ejecutar todo el comando sin problemas. Para ejecutar la secuencia de comandos build, escriba lo siguiente en su terminal:

      Verá el siguiente mensaje de inmediato:

      Output

      > digital-ocean-tutorial@0.1.0 build your_file_path/digital-ocean-tutorial > react-scripts build Creating an optimized production build... ...

      Esto le indica que Create React App está compilando su código en un paquete que se puede utilizar.

      Una vez que haya terminado, verá el siguiente resultado:

      Output

      ... Compiled successfully. File sizes after gzip: 39.85 KB build/static/js/9999.chunk.js 780 B build/static/js/runtime-main.99999.js 616 B build/static/js/main.9999.chunk.js 556 B build/static/css/main.9999.chunk.css The project was built assuming it is hosted at the server root. You can control this with the homepage field in your package.json. For example, add this to build it for GitHub Pages: "homepage" : "http://myname.github.io/myapp", The build folder is ready to be deployed. You may serve it with a static server: serve -s build Find out more about deployment here: bit.ly/CRA-deploy

      Enumere el contenido del proyecto; verá algunos directorios nuevos:

      Output

      build/ node_modules/ public/ src/ .gitignore README.md package-lock.json package.json

      Ahora tiene un directorio build. Si abrió el archivo .gitignore, debe haber notado que git ignora el directorio build. Esto se debe a que el directorio build es solo una versión reducida y optimizada de los otros archivos. No es necesario usar el control de versiones, dado que siempre puede ejecutar el comando build. Analizaremos el resultado más adelante; ahora, es momento de pasar a la secuencia de comandos test.

      La secuencia de comandos test

      La secuencia de comandos test es una de esas secuencias especiales que no requieren la palabra clave run, pero funcionará aun cuando la incluya. Esta secuencia de comandos iniciará un ejecutor de pruebas llamado Jest. El ejecutor de pruebas busca archivos con extensión .spec.js o .test.js en su proyecto y luego los ejecuta.

      Para ejecutar la secuencia de comandos test, escriba el siguiente comando:

      Después de ejecutar esta secuencia de comandos, tendrá el resultado del conjunto de pruebas en su terminal y el símbolo del sistema de la terminal desaparecerá. Se parecerá a esto:

      Output

      PASS src/App.test.js ✓ renders learn react link (67ms) Test Suites: 1 passed, 1 total Tests: 1 passed, 1 total Snapshots: 0 total Time: 4.204s Ran all test suites. Watch Usage › Press f to run only failed tests. › Press o to only run tests related to changed files. › Press q to quit watch mode. › Press p to filter by a filename regex pattern. › Press t to filter by a test name regex pattern. › Press Enter to trigger a test run.

      Hay algunas cosas que es necesario observar aquí. En primer lugar, como se indicó anteriormente, detecta automáticamente cualquier archivo que tenga una extensión de prueba, como .test.js y .spec.js.  En este caso, hay un solo conjunto de pruebas, es decir, un solo archivo con extensión .test.js, y ese conjunto de pruebas contiene una sola prueba. Jest puede detectar pruebas en su jerarquía de código; por lo tanto, puede anidar pruebas en un directorio y Jest las encontrará.

      En segundo lugar, Jest no ejecuta el conjunto de pruebas y, luego, sale. En su lugar, continúa ejecutándose en la terminal. Si realiza algún cambio del código fuente, volverá a ejecutar las pruebas.

      También puede limitar las pruebas que ejecuta usando una de las opciones del teclado. Si escribe o, por ejemplo, solo ejecutará pruebas en los archivos que se hayan modificado. Esto puede ahorrarle mucho tiempo cuando sus conjuntos de pruebas sean de mayor tamaño.

      Por último, puede salir del ejecutor de pruebas escribiendo q. Hágalo ahora para regresar al símbolo del sistema.

      La secuencia de comandos eject

      La última secuencia de comandos es npm eject. Esta secuencia copia sus dependencias y archivos de configuración a su proyecto, lo que le proporciona pleno control sobre su código y retira el proyecto de la cadena de herramientas integradas de Create React App. No la ejecutará en este momento, ya que si lo hace no podrá deshacer la acción y perderá toda actualización futura de Create React App.

      La ventaja de Create React App es que no debe preocuparse por realizar un trabajo de configuración considerable. La compilación de aplicaciones de JavaScript modernas requiere muchas herramientas, desde sistemas de compilación, como Webpack, hasta herramientas de compilación, como Babel. Create React App gestiona toda la configuración, por lo tanto, si retira el proyecto, deberá lidiar con esta complejidad usted mismo.

      La desventaja de Create React App es que no podrá personalizar del todo el proyecto.  Para la mayoría de los proyectos, no es un problema. Sin embargo, si alguna vez quiere tener el control de todos los aspectos del proceso de compilación, deberá retirar el código. Sin embargo, como se mencionó anteriormente, una vez que lo retire, no podrá actualizar a nuevas versiones de Create React App y deberá agregar cualquier mejora usted mismo de forma manual.

      En este punto, ejecutó secuencias de comandos para compilar y probar su código. En el siguiente paso, iniciará el proyecto en un servidor activo.

      Paso 3: Iniciar el servidor

      En este paso, iniciará un servidor local y ejecutará el proyecto en su navegador.

      Iniciará su proyecto con otra secuencia de comandos npm. Al igual que npm test, esta secuencia de comandos no requiere el comando run. Al ejecutar la secuencia de comandos, iniciará un servidor local, ejecutará el código del proyecto, iniciará un observador que detectará los cambios en el código y abrirá el proyecto en un navegador web.

      Inicie el proyecto escribiendo el siguiente comando en el directorio root de su proyecto. En este tutorial, el directorio root de su proyecto es digital-ocean-tutorial. Asegúrese de abrirlo en una terminal o una pestaña independiente, dado que esta secuencia de comandos seguirá ejecutándose mientras lo permita:

      Verá un texto de marcador de posición por un breve momento antes de que el servidor se inicie, lo que generará este resultado:

      Output

      Compiled successfully! You can now view digital-ocean-tutorial in the browser. http://localhost:3000 Note that the development build is not optimized. To create a production build, use npm run build.

      Si ejecuta la secuencia de comandos de forma local, abrirá el proyecto en la ventana de su navegador y cambiará el enfoque de la terminal al navegador.

      Si eso no sucede, puede visitar http://localhost:3000/ para ver el sitio en acción. Si ya tiene otro servidor en ejecución en el puerto 3000, no hay problema. Create React App detectará el siguiente puerto disponible y ejecutará el servidor en él. En otras palabras, si ya tiene un proyecto en ejecución en el puerto 3000, este nuevo proyecto se iniciará en el puerto 3001.

      Si ejecuta la secuencia de comandos desde un servidor remoto, de todos modos, puede ver su sitio sin configuración adicional. La dirección será http://your_server_ip:3000. Si tiene un firewall configurado, deberá abrir el puerto en su servidor remoto.

      En el navegador, verá el siguiente proyecto de plantilla de React:

      Proyecto de plantilla de React

      Tendrá un servidor local activo siempre que la secuencia de comandos se esté ejecutando. Para detener la secuencia de comandos, cierre la pestaña o la ventana de la terminal o escriba CTRL+C o ⌘-+c en la pestaña o la ventana de la terminal en donde se esté ejecutando.

      En este punto, inició el servidor y está ejecutando su primer código de React. Pero, antes de realizar modificaciones en el código JavaScript React, veremos cómo muestra React la representación en la página.

      Paso 4: Modificar la página de inicio

      En este paso, modificará el código en el directorio public/. El directorio public contiene su página HTML de base. Esta es la página que funcionará como root en su proyecto. Rara vez editará este directorio en el futuro, pero es la base desde la que se inicia el proyecto y es un elemento esencial de los proyectos de React.

      Si canceló su servidor, reinícielo con npm start, y luego abra public/ en el editor de texto que prefiera, en una ventana de terminal nueva:

      Alternativamente, puede enumerar los archivos con el comando ls:

      Verá una lista de archivos como la siguiente:

      Output

      favicon.ico logo192.png manifest.json index.html logo512.png robots.txt

      favicon.ico, logo192.png y logo512.png son íconos que los usuarios verían, ya sea en pestañas de sus navegadores o en sus teléfonos. El navegador seleccionará íconos del tamaño adecuado. Eventualmente, querrá sustituirlos por iconos que sean más adecuados para su proyecto. Por ahora, puede dejarlos como están.

      El archivo manifest.json es un conjunto estructurado de metadatos que describe su proyecto. Entre otras cosas, indica el icono que se usará para las distintas opciones de tamaños.

      El archivo robots.txt contiene información para los rastreadores web. Indica a los rastreadores las páginas que tienen permitido o no indexar. No necesitará cambiar ninguno de estos archivos a menos que haya un motivo imperioso para hacerlo. Por ejemplo, si quisiera darles a algunos usuarios la URL de un contenido especial que no desea que sea de fácil acceso, podría añadirla a robots.txt y seguiría estando disponible públicamente, pero los motores de búsqueda no la indexarían.

      El archivo index.html es el root de su aplicación. Este es el archivo que lee el servidor y el que se visualizará en su navegador. Ábralo en su editor de texto y obsérvelo.

      Si está trabajando en la línea de comandos, puede abrirla con el siguiente comando:

      Esto es lo que verá:

      digital-ocean-tutorial/public/index.html

      <!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="utf-8" />
          <link rel="icon" href="https://www.digitalocean.com/%PUBLIC_URL%/favicon.ico" />
          <meta name="viewport" content="width=device-width, initial-scale=1" />
          <meta name="theme-color" content="#000000" />
          <meta
            name="description"
            content="Web site created using create-react-app"
          />
          <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
          <!--
            manifest.json provides metadata used when your web app is installed on a
            user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
          -->
          <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
          <!--
            Notice the use of %PUBLIC_URL% in the tags above.
            It will be replaced with the URL of the `public` folder during the build.
            Only files inside the `public` folder can be referenced from the HTML.
      
            Unlike "https://www.digitalocean.com/favicon.ico" or "favicon.ico", "https://www.digitalocean.com/%PUBLIC_URL%/favicon.ico" will
            work correctly both with client-side routing and a non-root public URL.
            Learn how to configure a non-root public URL by running `npm run build`.
          -->
          <title>React App</title>
        </head>
        <body>
          <noscript>You need to enable JavaScript to run this app.</noscript>
          <div id="root"></div>
          <!--
            This HTML file is a template.
            If you open it directly in the browser, you will see an empty page.
      
            You can add webfonts, meta tags, or analytics to this file.
            The build step will place the bundled scripts into the <body> tag.
      
            To begin the development, run `npm start` or `yarn start`.
            To create a production bundle, use `npm run build` or `yarn build`.
          -->
        </body>
      </html>
      

      El archivo es bastante pequeño. No hay imágenes ni palabras en <body>. Esto se debe a que React crea toda la estructura HTML y la inserta con JavaScript. Pero React necesita saber dónde insertar el código, y esa es la función que cumple index.html.

      En su editor de texto, cambie la etiqueta <title> de React App a Sandbox:

      digital-ocean-tutorial/public/index.html

      <!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="utf-8" />
          <link rel="icon" href="https://www.digitalocean.com/%PUBLIC_URL%/favicon.ico" />
          <meta name="viewport" content="width=device-width, initial-scale=1" />
          <meta name="theme-color" content="#000000" />
          ...
          <title>Sandbox</title>
        </head>
        <body>
          <noscript>You need to enable JavaScript to run this app.</noscript>
          <div id="root"></div>
          <!--
            This HTML file is a template.
            If you open it directly in the browser, you will see an empty page.
      
            You can add webfonts, meta tags, or analytics to this file.
            The build step will place the bundled scripts into the <body> tag.
      
            To begin the development, run `npm start` or `yarn start`.
            To create a production bundle, use `npm run build` or `yarn build`.
          -->
        </body>
      </html>
      
      

      Guarde y salga del editor de texto. Revise su navegador. El título es el nombre que se encuentra en la pestaña del navegador. Se actualizará automáticamente. Si no es así, actualice la página y observe el cambio.

      Ahora, regrese al editor de texto. Todos los proyectos de React se inician a partir de un elemento root. Puede haber varios elementos root en una página, pero siempre debe haber uno como mínimo. Así es cómo React puede saber dónde agregar el código HTML generado. Busque el elemento <div id="root">. Este es el div que React usará para todas las actualizaciones futuras. Cambie la id de root a base:

      digital-ocean-tutorial/public/index.html

      <!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="utf-8" />
          ...
        <body>
          <noscript>You need to enable JavaScript to run this app.</noscript>
          <div id="base"></div>
          <!--
            This HTML file is a template.
            If you open it directly in the browser, you will see an empty page.
      
            You can add webfonts, meta tags, or analytics to this file.
            The build step will place the bundled scripts into the <body> tag.
      
            To begin the development, run `npm start` or `yarn start`.
            To create a production bundle, use `npm run build` or `yarn build`.
          -->
        </body>
      </html>
      

      Guarde los cambios.

      Verá un error en su navegador:

      Mensaje de error con la leyenda "Target container is not a DOM element"

      React buscaba un elemento con id root. Ahora que no está, React no puede iniciar el proyecto.

      Vuelva a cambiar el nombre de base a root:

      digital-ocean-tutorial/public/index.html

      <!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="utf-8" />
          ...
        <body>
          <noscript>You need to enable JavaScript to run this app.</noscript>
          <div id="root"></div>
          <!--
            This HTML file is a template.
            If you open it directly in the browser, you will see an empty page.
      
            You can add webfonts, meta tags, or analytics to this file.
            The build step will place the bundled scripts into the <body> tag.
      
            To begin the development, run `npm start` or `yarn start`.
            To create a production bundle, use `npm run build` or `yarn build`.
          -->
        </body>
      </html>
      

      Guarde y cierre index.html.

      En este punto, inició el servidor y realizó un cambio menor en la página HTML root. Todavía no cambió nada de código JavaScript. En la siguiente sección, actualizará el código de JavaScript React.

      Paso 5: Modificar la etiqueta de encabezado y el estilo

      En este paso, realizará su primer cambio a un componente de React en el directorio src/. Realizará un cambio menor en el código CSS y JavaScript que se actualizará de forma automática en su navegador con la recarga directa incorporada.

      Si detuvo el servidor, asegúrese de reiniciarlo con npm start. Ahora, tómese un tiempo para observar los componentes del directorio src/. Puede abrir todo el directorio en el editor de texto que prefiera o enumerar el proyecto en una terminal con el siguiente comando:

      Verá los siguientes archivos en su terminal o editor de texto.

      Output

      App.css App.js App.test.js index.css index.js logo.svg serviceWorker.js setupTests.js

      Analicemos cada uno de estos archivos.

      Al principio, no invertirá mucho tiempo en el archivo serviceWorker.js, pero puede ser importante al comenzar a crear aplicaciones web progresivas. El trabajo de servicio puede hacer muchas cosas, entre ellas, insertar notificaciones y almacenar en caché sin conexión, pero, por el momento, es mejor no modificarlo.

      Los siguientes archivos que analizaremos son setupTests.js y App.test.js. Se utilizan para los archivos de prueba. De hecho, cuando ejecutó npm test en el paso 2, la secuencia de comandos ejecutó estos archivos. El archivo setupTests.js es pequeño; solo incluye algunos métodos expect personalizados. Obtendrá más información sobre estos archivos en tutoriales futuros de esta serie.

      Abra App.test.js:

      Al abrirlo, verá una prueba básica:

      digital-ocean-tutorial/src/App.test.js

      import React from 'react';
      import { render } from '@testing-library/react';
      import App from './App';
      
      test('renders learn react link', () => {
        const { getByText } = render(<App />);
        const linkElement = getByText(/learn react/i);
        expect(linkElement).toBeInTheDocument();
      });
      

      La prueba busca la frase learn react en el documento. Si regresa al navegador en el que se ejecuta su proyecto, verá la frase en la página. Las pruebas de React son diferentes de la mayoría de las pruebas de unidades. Dado que los componentes pueden incluir información visual, como marcado, además de la lógica para manipular datos, las pruebas unitarias tradicionales no funcionan tan fácilmente.  Las pruebas de React son más similares a una clase de pruebas funcionales o de integración.

      A continuación, veremos algunos archivos de estilo: App.css, index.css y logo.svg. Hay varias formas de trabajar con estilos en React, pero lo más sencillo es escribir en CSS simple, ya que no requiere configuración adicional.

      Hay varios archivos CSS porque puede importar los estilos en un componente como si fueran otro archivo de JavaScript.  Como puede importar CSS directamente a un componente, también podría dividirlo para que solo se aplique a un componente individual. Lo que hará es separar cuestiones.  No mantendrá todo el CSS separado del JavaScript. Lo que está haciendo es mantener todo el CSS, el JavaScript, el marcado y las imágenes relacionados agrupados.

      Abra App.css en su editor de texto. Si trabaja en la línea de comandos, puede abrirla con el siguiente comando:

      Este es el código que verá:

      digital-ocean-tutorial/src/App.css

      .App {
        text-align: center;
      }
      
      .App-logo {
        height: 40vmin;
        pointer-events: none;
      }
      
      @media (prefers-reduced-motion: no-preference) {
        .App-logo {
          animation: App-logo-spin infinite 20s linear;
        }
      }
      
      .App-header {
        background-color: #282c34;
        min-height: 100vh;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        font-size: calc(10px + 2vmin);
        color: white;
      }
      
      .App-link {
        color: #61dafb;
      }
      
      @keyframes App-logo-spin {
        from {
          transform: rotate(0deg);
        }
        to {
          transform: rotate(360deg);
        }
      }
      

      Este es un archivo CSS estándar sin preprocesadores especiales. Si lo desea, puede agregarlos más adelante, pero, al principio, solo tendrá CSS simple. Create React App trata de mantenerse flexible sin dejar de proporcionar un entorno listo para usar.

      Volviendo a App.css, uno de los beneficios de usar Create React App es que inspecciona todos los archivos; por lo tanto, si realiza un cambio lo verá en su navegador sin volver a cargarlo.

      Para ver cómo funciona, haga un cambio menor a background-color en App.css. Cambie el valor de #282c34 a blue y guarde el archivo. El estilo final tendrá el siguiente aspecto:

      digital-ocean-tutorial/src/App.css

      .App {
        text-align: center;
      }
      ...
      .App-header {
        background-color: blue
        min-height: 100vh;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        font-size: calc(10px + 2vmin);
        color: white;
      }
      ...
      
      @keyframes App-logo-spin {
        from {
          transform: rotate(0deg);
        }
        to {
          transform: rotate(360deg);
        }
      }
      

      Revise su navegador. Así es como se veía anteriormente:

      React app con fondo oscuro

      Así es como se verá después del cambio:

      React app con fondo azul

      Vuelva a cambiar background-color a #282c34.

      digital-ocean-tutorial/src/App.css

      .App {
        text-align: center;
      
      ...
      
      .App-header {
        background-color: #282c34
        min-height: 100vh;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        font-size: calc(10px + 2vmin);
        color: white;
      }
      
      ...
      
      @keyframes App-logo-spin {
        from {
          transform: rotate(0deg);
        }
        to {
          transform: rotate(360deg);
        }
      }
      

      Guarde el archivo y ciérrelo.

      Hizo un cambio menor en CSS. Ahora, es momento de realizar cambios en el código JavaScript React. Comience abriendo index.js.

      Esto es lo que verá:

      digital-ocean-tutorial/src/index.js

      import React from 'react';
      import ReactDOM from 'react-dom';
      import './index.css';
      import App from './App';
      import * as serviceWorker from './serviceWorker';
      
      ReactDOM.render(<App />, document.getElementById('root'));
      
      // If you want your app to work offline and load faster, you can change
      // unregister() to register() below. Note this comes with some pitfalls.
      // Learn more about service workers: https://bit.ly/CRA-PWA
      serviceWorker.unregister();
      

      En la parte superior, importará React, ReactDOM, index.css, App y serviceWorker. Al importar React, en realidad, está extrayendo código para convertir JSX a JavaScript. JSX son elementos similares a HTML. Por ejemplo, observe cómo cuando usa App lo trata como un elemento HTML <App />. Verá esto en más detalle en tutoriales futuros de esta serie.

      ReactDOM es el código que conecta su código de React con los elementos básicos, como la página index.html que vio en public/. Observe la siguiente línea resaltada:

      digital-ocean-tutorial/src/index.js

      ...
      import * as serviceWorker from './serviceWorker';
      
      ReactDOM.render(<App />, document.getElementById('root'));
      ...
      serviceWorker.unregister();
      

      Este código indica a React que busque un elemento con id root e inserte su código allí. <App/> es su elemento root, y todo partirá de allí. Este es el punto de partida para todo el código de React futuro.

      En la parte superior del archivo, verá algunas importaciones. Importa index.css, pero en realidad no hace nada con él. Al importarlo, indica a Webpack, a través de las secuencias de comandos de React, que incluya el código CSS en el paquete compilado final. Si no lo importa, no aparecerá.

      Cierre src/index.js.

      En este punto, todavía no vio nada que de lo que está viendo en su navegador. Para verlo, abra App.js:

      El código de este archivo se verá como una serie de elementos HTML comunes. Esto es lo que verá:

      digital-ocean-tutorial/src/App.js

      import React from 'react';
      import logo from './logo.svg';
      import './App.css';
      
      function App() {
        return (
          <div className="App">
            <header className="App-header">
              <img src={logo} className="App-logo" alt="logo" />
              <p>
                Edit <code>src/App.js</code> and save to reload.
              </p>
              <a
                className="App-link"
                href="https://reactjs.org"
                target="_blank"
                rel="noopener noreferrer"
              >
                Learn React
              </a>
            </header>
          </div>
        );
      }
      
      export default App;
      

      Cambie el contenido de la etiqueta <p> de Edit <code>src/App.js</code> and save to reload. a Hello world y guarde los cambios.

      digital-ocean-tutorial/src/App.js

      ...
      
      function App() {
        return (
          <div className="App">
            <header className="App-header">
              <img src={logo} className="App-logo" alt="logo" />
              <p>
                  Hello, world
              </p>
              <a
                className="App-link"
                href="https://reactjs.org"
                target="_blank"
                rel="noopener noreferrer"
              >
                Learn React
              </a>
            </header>
          </div>
        );
      }
      ...
      

      Diríjase a su navegador para ver el cambio:

      React app con "Hello, world" en la etiqueta de párrafo

      Ahora, hizo su primera actualización de un componente de React.

      Antes de terminar, observe algunas cosas más. En este componente, importa el archivo logo.svg y lo asigna a una variable. Luego, en el elemento <img>, añade ese código como src.

      Aquí están ocurriendo algunas cosas. Observe el elemento img:

      digital-ocean-tutorial/src/App.js

      ...
      function App() {
        return (
          <div className="App">
            <header className="App-header">
              <img src={logo} className="App-logo" alt="logo" />
              <p>
                  Hello, world
              </p>
      ...
      

      Observe que logo se pasa entre llaves. Para pasar atributos que no senn cadenas ni números, debe usar llaves. React los tratará como JavaScript en vez de cadenas. En este caso, en realidad, no importará la imagen: hará referencia a ella. Cuando Webpack crea el proyecto, maneja la imagen y establece la fuente en el lugar correspondiente.

      Cierre el editor de texto.

      Si observa los elementos DOM en su navegador, verá que añade una ruta. Si usa Chrome, puede inspeccionar el elemento haciendo clic en él y seleccionando Inspeccionar.

      Así es como se verá en el navegador:

      Inspeccionar elementos con herramientas de desarrollo de Chrome

      El DOM tiene esta línea:

      <img src="https://www.digitalocean.com/static/media/logo.5d5d9eef.svg" class="App-logo" alt="logo">
      

      Su código será ligeramente distinto, ya que el logo tendrá un nombre diferente. Webpack quiere asegurarse de que la ruta a la imagen sea única. Por lo tanto, incluso si importa imágenes con el mismo nombre, se guardarán en diferentes rutas.

      En este punto, realizó un cambio menor en el código Javascript React. En el siguiente paso, usará el comando build para reducir el código a un archivo pequeño que se puede implementar en un servidor.

      Paso 6: Compilar el proyecto

      En este paso, compilará el código en un paquete que se puede implementar en servidores externos.

      Regrese a su terminal y compile el proyecto. Ejecutó este comando antes, pero recuerde que este comando ejecutará la secuencia de comandos build. Creará un directorio nuevo con los archivos combinados y reducidos. Para ejecutar la compilación, ejecute el siguiente comando desde el root de su proyecto:

      La compilación del código tomará un tiempo y, cuando se complete, tendrá un directorio nuevo denominado build/.

      Abra build/index.html en un editor de texto.

      Verá algo similar a esto:

      digital-ocean-tutorial/build/index.html

      <!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="https://www.digitalocean.com/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="http://www.digitalocean.com/logo192.png"/><link rel="manifest" href="http://www.digitalocean.com/manifest.json"/><title>React App</title><link href="http://www.digitalocean.com/static/css/main.d1b05096.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function r(r){for(var n,a,p=r[0],l=r[1],c=r[2],i=0,s=[];i<p.length;i++)a=p[i],Object.prototype.hasOwnProperty.call(o,a)&&o[a]&&s.push(o[a][0]),o[a]=0;for(n in l)Object.prototype.hasOwnProperty.call(l,n)&&(e[n]=l[n]);for(f&&f(r);s.length;)s.shift()();return u.push.apply(u,c||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,p=1;p<t.length;p++){var l=t[p];0!==o[l]&&(n=!1)}n&&(u.splice(r--,1),e=a(a.s=t[0]))}return e}var n={},o={1:0},u=[];function a(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,a),t.l=!0,t.exports}a.m=e,a.c=n,a.d=function(e,r,t){a.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,r){if(1&r&&(e=a(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(a.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)a.d(t,n,function(r){return e[r]}.bind(null,n));return t},a.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(r,"a",r),r},a.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},a.p="/";var p=this["webpackJsonpdo-create-react-app"]=this["webpackJsonpdo-create-react-app"]||[],l=p.push.bind(p);p.push=r,p=p.slice();for(var c=0;c<p.length;c++)r(p[c]);var f=l;t()}([])</script><script src="/static/js/2.c0be6967.chunk.js"></script><script src="/static/js/main.bac2dbd2.chunk.js"></script></body></html>
      

      El directorio build toma todo el código y lo compila y reduce al menor estado utilizable. No importa si un humano puede leerlo o no, dado que no es una porción de código que estará disponible al público. Esta reducción hará que el código ocupe menos espacio, pero siga funcionando.  A diferencia de algunos lenguajes como Python, el espacio en blanco no modifica la forma en que la computadora interpreta el código.

      Conclusión

      En este tutorial, creó su primera aplicación de React y configuró su proyecto con herramientas de compilación de JavaScript sin necesidad de entrar en detalles técnicos. Ese es el beneficio de Create React App: no es necesario conocerla a fondo para comenzar a usarla. Le permite ignorar los pasos complicados de la compilación para que se pueda centrar exclusivamente en el código de React.

      Aprendió los comandos para iniciar, probar y compilar un proyecto. Usará estos comandos de forma regular; por lo tanto, tome nota de ellos para tutoriales futuros. Lo más importante es que actualizó su primer componente de React.

      Si desea ver React en acción, consulte nuestro tutorial Cómo visualizar datos de la API de DigitalOcean con React.



      Source link