One place for hosting & domains

      How To Manage State on React Class Components


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

      Introduction

      In React, state refers to a structure that keeps track of how data changes over time in your application. Managing state is a crucial skill in React because it allows you to make interactive components and dynamic web applications. State is used for everything from tracking form inputs to capturing dynamic data from an API. In this tutorial, you’ll run through an example of managing state on class-based components.

      As of the writing of this tutorial, the official React documentation encourages developers to adopt React Hooks to manage state with functional components when writing new code, rather than using class-based components. Although the use of React Hooks is considered a more modern practice, it’s important to understand how to manage state on class-based components as well. Learning the concepts behind state management will help you navigate and troubleshoot class-based state management in existing code bases and help you decide when class-based state management is more appropriate. There’s also a class-based method called componentDidCatch that is not available in Hooks and will require setting state using class methods.

      This tutorial will first show you how to set state using a static value, which is useful for cases where the next state does not depend on the first state, such as setting data from an API that overrides old values. Then it will run through how to set a state as the current state, which is useful when the next state depends on the current state, such as toggling a value. To explore these different ways of setting state, you’ll create a product page component that you’ll update by adding purchases from a list of options.

      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 sample application for managing state on class-based components.

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

      • npx create-react-app state-class-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:

      state-class-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:

      state-class-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 your custom components.

      Each component will have its own directory to store the component file along with the styles, images, 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:

      state-class-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 — Using State in a Component

      In this step, you’ll set the initial state of a component on its class and reference the state to display a value. You’ll then make a product page with a shopping cart that displays the total items in the cart using the state value. By the end of the step, you’ll know the different ways to hold a value and when you should use state rather than a prop or a static value.

      Building the Components

      Start by creating a directory for Product:

      • mkdir src/components/Product

      Next, open up Product.js in that directory:

      • nano src/components/Product/Product.js

      Start by creating a component with no state. The component will have two parts: The cart, which has the number of items and the total price, and the product, which has a button to add and remove an item. For now, the buttons will have no actions.

      Add the following code to Product.js:

      state-class-tutorial/src/components/Product/Product.js

      import React, { Component } from 'react';
      import './Product.css';
      
      export default class Product extends Component {
        render() {
          return(
            <div className="wrapper">
              <div>
                Shopping Cart: 0 total items.
              </div>
              <div>Total: 0</div>
      
              <div className="product"><span role="img" aria-label="ice cream">🍦</span></div>
              <button>Add</button> <button>Remove</button>
            </div>
          )
        }
      }
      

      You have also included a couple of div elements that have JSX class names so you can add some basic styling.

      Save and close the file, then open Product.css:

      • nano src/components/Product/Product.css

      Give some light styling to increase the font-size for the text and the emoji:

      state-class-tutorial/src/components/Product/Product.css

      .product span {
          font-size: 100px;
      }
      
      .wrapper {
          padding: 20px;
          font-size: 20px;
      }
      
      .wrapper button {
          font-size: 20px;
          background: none;
      }
      

      The emoji will need a much larger font size than the text, since it’s acting as the product image in this example. In addition, you are removing the default gradient background on buttons by setting the background to none.

      Save and close the file.

      Now, render the Product component in the App component so you can see the results in the browser. Open App.js:

      • nano src/components/App/App.js

      Import the component and render it. You can also delete the CSS import since you won’t be using it in this tutorial:

      state-class-tutorial/src/components/App/App.js

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

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

      Product Page

      Setting the Initial State on a Class Component

      There are two values in your component values that are going to change in your display: total number of items and total cost. Instead of hard coding them, in this step you’ll move them into an object called state.

      The state of a React class is a special property that controls the rendering of a page. When you change the state, React knows that the component is out-of-date and will automatically re-render. When a component re-renders, it modifies the rendered output to include the most up-to-date information in state. In this example, the component will re-render whenever you add a product to the cart or remove it from the cart. You can add other properties to a React class, but they won’t have the same ability to trigger re-rendering.

      Open Product.js:

      • nano src/components/Product/Product.js

      Add a property called state to the Product class. Then add two values to the state object: cart and total. The cart will be an array, since it may eventually hold many items. The total will be a number. After assigning these, replace references to the values with this.state.property:

      state-class-tutorial/src/components/Product/Product.js

      
      import React, { Component } from 'react';
      import './Product.css';
      
      export default class Product extends Component {
      
        state = {
          cart: [],
          total: 0
        }
      
        render() {
          return(
            <div className="wrapper">
              <div>
                Shopping Cart: {this.state.cart.length} total items.
              </div>
              <div>Total {this.state.total}</div>
      
              <div className="product"><span role="img" aria-label="ice cream">🍦</span></div>
              <button>Add</button> <button>Remove</button>
            </div>
          )
        }
      }
      

      Notice that in both cases, since you are referencing JavaScript inside of your JSX, you need to wrap the code in curly braces. You are also displaying the length of the cart array to get a count of the number of items in the array.

      Save the file. When you do, the browser will refresh and you’ll see the same page as before.

      Product Page

      The state property is a standard class property, which means that it is accessible in other methods, not just the render method.

      Next, instead of displaying the price as a static value, convert it to a string using the toLocaleString method, which will convert the number to a string that matches the way numbers are displayed in the browser’s region.

      Create a method called getTotal() that takes the state and converts it to a localized string using an array of currencyOptions. Then, replace the reference to state in the JSX with a method call:

      state-class-tutorial/src/components/Product/Product.js

      import React, { Component } from 'react';
      import './Product.css';
      
      export default class Product extends Component {
      
        state = {
          cart: [],
          total: 0
        }
      
        currencyOptions = {
          minimumFractionDigits: 2,
          maximumFractionDigits: 2,
        }
      
        getTotal = () => {
          return this.state.total.toLocaleString(undefined, this.currencyOptions)
        }
      
        render() {
          return(
            <div className="wrapper">
              <div>
                Shopping Cart: {this.state.cart.length} total items.
              </div>
              <div>Total {this.getTotal()}</div>
      
              <div className="product"><span role="img" aria-label="ice cream">🍦</span></div>
              <button>Add</button> <button>Remove</button>
            </div>
          )
        }
      }
      

      Since total is a price for goods, you are passing currencyOptions that set the maximum and minimum decimal places for your total to two. Note that this is set as a separate property. Often, beginner React developers will put information like this in the state object, but it is best to only add information to state that you expect to change. This way, the information in state will be easier to keep strack of as your application scales.

      Another important change you made was to create the getTotal() method by assigning an arrow function to a class property. Without using the arrow function, this method would create a new this binding, which would interfere with the current this binding and introduce a bug into our code. You’ll see more on this in the next step.

      Save the file. When you do, the page will refresh and you’ll see the value converted to a decimal.

      Price converted to decimal

      You’ve now added state to a component and referenced it in your class. You also accessed values in the render method and in other class methods. Next, you’ll create methods to update the state and show dynamic values.

      Step 3 — Setting State from a Static Value

      So far you’ve created a base state for the component and you’ve referenced that state in your functions and your JSX code. In this step, you’ll update your product page to modify the state on button clicks. You’ll learn how to pass a new object containing updated values to a special method called setState, which will then set the state with the updated data.

      To update state, React developers use a special method called setState that is inherited from the base Component class. The setState method can take either an object or a function as the first argument. If you have a static value that doesn’t need to reference the state, it’s best to pass an object containing the new value, since it’s easier to read. If you need to reference the current state, you pass a function to avoid any references to out-of-date state.

      Start by adding an event to the buttons. If your user clicks Add, then the program will add the item to the cart and update the total. If they click Remove, it will reset the cart to an empty array and the total to 0. For example purposes, the program will not allow a user to add an item more then once.

      Open Product.js:

      • nano src/components/Product/Product.js

      Inside the component, create a new method called add, then pass the method to the onClick prop for the Add button:

      state-class-tutorial/src/components/Product/Product.js

      import React, { Component } from 'react';
      import './Product.css';
      
      export default class Product extends Component {
      
        state = {
          cart: [],
          total: 0
        }
      
        add = () => {
          this.setState({
            cart: ['ice cream'],
            total: 5
          })
        }
      
        currencyOptions = {
          minimumFractionDigits: 2,
          maximumFractionDigits: 2,
        }
      
        getTotal = () => {
          return this.state.total.toLocaleString(undefined, this.currencyOptions)
        }
      
        render() {
          return(
            <div className="wrapper">
              <div>
                Shopping Cart: {this.state.cart.length} total items.
              </div>
              <div>Total {this.getTotal()}</div>
      
              <div className="product"><span role="img" aria-label="ice cream">🍦</span></div>
              <button onClick={this.add}>Add</button>
              <button>Remove</button>
            </div>
          )
        }
      }
      

      Inside the add method, you call the setState method and pass an object containing the updated cart with a single item ice cream and the updated price of 5. Notice that you again used an arrow function to create the add method. As mentioned before, this will ensure the function has the proper this context when running the update. If you add the function as a method without using the arrow function, the setState would not exist without binding the function to the current context.

      For example, if you created the add function this way:

      export default class Product extends Component {
      ...
        add() {
          this.setState({
            cart: ['ice cream'],
            total: 5
          })
        }
      ...
      }
      

      The user would get an error when they click on the Add button.

      Context Error

      Using an arrow function ensures that you’ll have the proper context to avoid this error.

      Save the file. When you do, the browser will reload, and when you click on the Add button the cart will update with the current amount.

      Click on the button and see state updated

      With the add method, you passed both properties of the state object: cart and total. However, you do not always need to pass a complete object. You only need to pass an object containing the properties that you want to update, and everything else will stay the same.

      To see how React can handle a smaller object, create a new function called remove. Pass a new object containing just the cart with an empty array, then add the method to the onClick property of the Remove button:

      state-class-tutorial/src/components/Product/Product.js

      import React, { Component } from 'react';
      import './Product.css';
      
      export default class Product extends Component {
      
        ...
        remove = () => {
          this.setState({
            cart: []
          })
        }
      
        render() {
          return(
            <div className="wrapper">
              <div>
                Shopping Cart: {this.state.cart.length} total items.
              </div>
              <div>Total {this.getTotal()}</div>
      
              <div className="product"><span role="img" aria-label="ice cream">🍦</span></div>
              <button onClick={this.add}>Add</button>
              <button onClick={this.remove}>Remove</button>
            </div>
          )
        }
      }
      

      Save the file. When the browser refreshes, click on the Add and Remove buttons. You’ll see the cart update, but not the price. The total state value is preserved during the update. This value is only preserved for example purposes; with this application, you would want to update both properties of the state object. But you will often have components with stateful properties that have different responsibilities, and you can make them persist by leaving them out of the updated object.

      The change in this step was static. You knew exactly what the values would be ahead of time, and they didn’t need to be recalculated from state. But if the product page had many products and you wanted to be able to add them multiple times, passing a static object would provide no guarantee of referencing the most up-to-date state, even if your object used a this.state value. In this case, you could instead use a function.

      In the next step, you’ll update state using functions that reference the current state.

      Step 4 — Setting State Using Current State

      There are many times when you’ll need to reference a previous state to update a current state, such as updating an array, adding a number, or modifying an object. To be as accurate as possible, you need to reference the most up-to-date state object. Unlike updating state with a predefined value, in this step you’ll pass a function to the setState method, which will take the current state as an argument. Using this method, you will update a component’s state using the current state.

      Another benefit of setting state with a function is increased reliability. To improve performance, React may batch setState calls, which means that this.state.value may not be fully reliable. For example, if you update state quickly in several places, it is possible that a value could be out of date. This can happen during data fetches, form validations, or any situation where several actions are occurring in parallel. But using a function with the most up-to-date state as the argument ensures that this bug will not enter your code.

      To demonstrate this form of state management, add some more items to the product page. First, open the Product.js file:

      • nano src/components/Product/Product.js

      Next, create an array of objects for different products. The array will contain the product emoji, name, and price. Then loop over the array to display each product with an Add and Remove button:

      state-class-tutorial/src/components/Product/Product.js

      import React, { Component } from 'react';
      import './Product.css';
      
      const products = [
        {
          emoji: '🍦',
          name: 'ice cream',
          price: 5
        },
        {
          emoji: '🍩',
          name: 'donuts',
          price: 2.5,
        },
        {
          emoji: '🍉',
          name: 'watermelon',
          price: 4
        }
      ];
      
      export default class Product extends Component {
      
        ...
      
      
        render() {
          return(
            <div className="wrapper">
              <div>
                Shopping Cart: {this.state.cart.length} total items.
              </div>
              <div>Total {this.getTotal()}</div>
              <div>
                {products.map(product => (
                  <div key={product.name}>
                    <div className="product">
                      <span role="img" aria-label={product.name}>{product.emoji}</span>
                    </div>
                    <button onClick={this.add}>Add</button>
                    <button onClick={this.remove}>Remove</button>
                  </div>
                ))}
              </div>
            </div>
          )
        }
      }
      

      In this code, you are using the map() array method to loop over the products array and return the JSX that will display each element in your browser.

      Save the file. When the browser reloads, you’ll see an updated product list:

      Product list

      Now you need to update your methods. First, change the add() method to take the product as an argument. Then instead of passing an object to setState(), pass a function that takes the state as an argument and returns an object that has the cart updated with the new product and the total updated with the new price:

      state-class-tutorial/src/components/Product/Product.js

      import React, { Component } from 'react';
      import './Product.css';
      
      ...
      
      export default class Product extends Component {
      
        state = {
          cart: [],
          total: 0
        }
      
        add = (product) => {
          this.setState(state => ({
            cart: [...state.cart, product.name],
            total: state.total + product.price
          }))
        }
      
        currencyOptions = {
          minimumFractionDigits: 2,
          maximumFractionDigits: 2,
        }
      
        getTotal = () => {
          return this.state.total.toLocaleString(undefined, this.currencyOptions)
        }
      
        remove = () => {
          this.setState({
            cart: []
          })
        }
      
        render() {
          return(
            <div className="wrapper">
              <div>
                Shopping Cart: {this.state.cart.length} total items.
              </div>
              <div>Total {this.getTotal()}</div>
      
              <div>
                {products.map(product => (
                  <div key={product.name}>
                    <div className="product">
                      <span role="img" aria-label={product.name}>{product.emoji}</span>
                    </div>
                    <button onClick={() => this.add(product)}>Add</button>
                    <button onClick={this.remove}>Remove</button>
                  </div>
                ))}
              </div>
            </div>
          )
        }
      }
      

      Inside the anonymous function that you pass to setState(), make sure you reference the argument—state—and not the component’s state—this.state. Otherwise, you still run a risk of getting an out-of-date state object. The state in your function will be otherwise identical.

      Take care not to directly mutate state. Instead, when adding a new value to the cart, you can add the new product to the state by using the spread syntax on the current value and adding the new value onto the end.

      Finally, update the call to this.add by changing the onClick() prop to take an anonymous function that calls this.add() with the relevant product.

      Save the file. When you do, the browser will reload and you’ll be able to add multiple products.

      Adding products

      Next, update the remove() method. Follow the same steps: convert setState to take a function, update the values without mutating, and update the onChange() prop:

      state-class-tutorial/src/components/Product/Product.js

      import React, { Component } from 'react';
      import './Product.css';
      
      ...
      
      export default class Product extends Component {
      
      ...
      
        remove = (product) => {
          this.setState(state => {
            const cart = [...state.cart];
            cart.splice(cart.indexOf(product.name))
            return ({
              cart,
              total: state.total - product.price
            })
          })
        }
      
        render() {
          return(
            <div className="wrapper">
              <div>
                Shopping Cart: {this.state.cart.length} total items.
              </div>
              <div>Total {this.getTotal()}</div>
              <div>
                {products.map(product => (
                  <div key={product.name}>
                    <div className="product">
                      <span role="img" aria-label={product.name}>{product.emoji}</span>
                    </div>
                    <button onClick={() => this.add(product)}>Add</button>
                    <button onClick={() => this.remove(product)}>Remove</button>
                  </div>
                ))}
              </div>
            </div>
          )
        }
      }
      

      To avoid mutating the state object, you must first make a copy of it using the spread operator. Then you can splice out the item you want from the copy and return the copy in the new object. By copying state as the first step, you can be sure that you will not mutate the state object.

      Save the file. When you do, the browser will refresh and you’ll be able to add and remove items:

      Remove items

      There is still a bug in this application: In the remove method, a user can subtract from the total even if the item is not in the cart. If you click Remove on the ice cream without adding it to your cart, your total will be -5.00.

      You can fix the bug by checking for an item’s existence before subtracting, but an easier way is to keep your state object small by only keeping references to the products and not separating references to products and total cost. Try to avoid double references to the same data. Instead, store the raw data in state— in this case the whole product object—then perform the calculations outside of the state.

      Refactor the component so that the add() method adds the whole object, the remove() method removes the whole object, and the getTotal method uses the cart:

      state-class-tutorial/src/components/Product/Product.js

      import React, { Component } from 'react';
      import './Product.css';
      
      ...
      
      export default class Product extends Component {
      
        state = {
          cart: [],
        }
      
        add = (product) => {
          this.setState(state => ({
            cart: [...state.cart, product],
          }))
        }
      
        currencyOptions = {
          minimumFractionDigits: 2,
          maximumFractionDigits: 2,
        }
      
        getTotal = () => {
          const total = this.state.cart.reduce((totalCost, item) => totalCost + item.price, 0);
          return total.toLocaleString(undefined, this.currencyOptions)
        }
      
        remove = (product) => {
          this.setState(state => {
            const cart = [...state.cart];
            const productIndex = cart.findIndex(p => p.name === product.name);
            if(productIndex < 0) {
              return;
            }
            cart.splice(productIndex, 1)
            return ({
              cart
            })
          })
        }
      
        render() {
          ...
        }
      }
      

      The add() method is similar to what it was before, except that reference to the total property has been removed. In the remove() method, you find the index of the product with findByIndex. If the index doesn’t exist, you’ll get a -1. In that case, you use a conditional statement toreturn nothing. By returning nothing, React will know the state didn’t change and won’t trigger a re-render. If you return state or an empty object, it will still trigger a re-render.

      When using the splice() method, you are now passing 1 as the second argument, which will remove one value and keep the rest.

      Finally, you calculate the total using the reduce() array method.

      Save the file. When you do, the browser will refresh and you’ll have your final cart:

      Add and remove

      The setState function you pass can have an additional argument of the current props, which can be helpful if you have state that needs to reference the current props. You can also pass a callback function to setState as the second argument, regardless of if you pass an object or function for the first argument. This is particularly useful when you are setting state after fetching data from an API and you need to perform a new action after the state update is complete.

      In this step, you learned how to update a new state based on the current state. You passed a function to the setState function and calculated new values without mutating the current state. You also learned how to exit a setState function if there is no update in a manner that will prevent a re-render, adding a slight performance enhancement.

      Conclusion

      In this tutorial, you have developed a class-based component with a dynamic state that you’ve updated statically and using the current state. You now have the tools to make complex projects that respond to users and dynamic information.

      React does have a way to manage state with Hooks, but it is helpful to understand how to use state on components if you need to work with components that must be class-based, such as those that use the componentDidCatch method.

      Managing state is key to nearly all components and is necessary for creating interactive applications. With this knowledge you can recreate many common web components, such as sliders, accordions, forms, and more. You will then use the same concepts as you build applications using hooks or develop components that pull data dynamically from APIs.

      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

      Understanding Template Literals in JavaScript


      The author selected the COVID-19 Relief Fund to receive a donation as part of the Write for DOnations program.

      Introduction

      The 2015 edition of the ECMAScript specification (ES6) added template literals to the JavaScript language. Template literals are a new form of making strings in JavaScript that add a lot of powerful new capabilities, such as creating multi-line strings more easily and using placeholders to embed expressions in a string. In addition, an advanced feature called tagged template literals allows you to perform operations on the expressions within a string. All of these capabilities increase your options for string manipulation as a developer, letting you generate dynamic strings that could be used for URLs or functions that customize HTML elements.

      In this article, you will go over the differences between single/double-quoted strings and template literals, running through the various ways to declare strings of different shape, including multi-line strings and dynamic strings that change depending on the value of a variable or expression. You will then learn about tagged templates and see some real-world examples of projects using them.

      Declaring Strings

      This section will review how to declare strings with single quotes and double quotes, and will then show you how to do the same with template literals.

      In JavaScript, a string can be written with single quotes (' '):

      const single="Every day is a good day when you paint."
      

      A string can also be written with double quotes (" "):

      const double = "Be so very light. Be a gentle whisper."
      

      There is no major difference in JavaScript between single- or double-quoted strings, unlike other languages that might allow interpolation in one type of string but not the other. In this context, interpolation refers to the evaluation of a placeholder as a dynamic part of a string.

      The use of single- or double-quoted strings mostly comes down to personal preference and convention, but used in conjunction, each type of string only needs to escape its own type of quote:

      // Escaping a single quote in a single-quoted string
      const single=""We don"t make mistakes. We just have happy accidents." - Bob Ross'
      
      // Escaping a double quote in a double-quoted string
      const double = ""We don't make mistakes. We just have happy accidents." - Bob Ross"
      
      console.log(single);
      console.log(double);
      

      The result of the log() method here will print the same two strings to the console:

      Output

      "We don't make mistakes. We just have happy accidents." - Bob Ross "We don't make mistakes. We just have happy accidents." - Bob Ross

      Template literals, on the other hand, are written by surrounding the string with the backtick character, or grave accent (`):

      const template = `Find freedom on this canvas.`
      

      They do not need to escape single or double quotes:

      const template = `"We don't make mistakes. We just have happy accidents." - Bob Ross`
      

      However, they do still need to escape backticks:

      const template = `Template literals use the ` character.`
      

      Template literals can do everything that regular strings can, so you could possibly replace all strings in your project with them and have the same functionality. However, the most common convention in codebases is to only use template literals when using the additional capabilities of template literals, and consistently using the single or double quotes for all other simple strings. Following this standard will make your code easier to read if examined by another developer.

      Now that you’ve seen how to declare strings with single quotes, double quotes, and backticks, you can move on to the first advantage of template literals: writing multi-line strings.

      Multi-line Strings

      In this section, you will first run through the way strings with multiple lines were declared before ES6, then see how template literals make this easier.

      Originally, if you wanted to write a string that spans multiple lines in your text editor, you would use the concatenation operator. However, this was not always a straight-forward process. The following string concatenation seemed to run over multiple lines:

      const address="Homer J. Simpson" + 
        '742 Evergreen Terrace' + 
        'Springfield'
      

      This might allow you to break up the string into smaller lines and include it over multiple lines in the text editor, but it has no effect on the output of the string. In this case, the strings will all be on one line and not separated by newlines or spaces. If you logged address to the console, you would get the following:

      Output

      Homer J. Simpson742 Evergreen TerraceSpringfield

      You can use the backslash character () to continue the string onto multiple lines:

      const address="Homer J. Simpson
        742 Evergreen Terrace
        Springfield"
      

      This will retain any indentation as whitespace, but the string will still be on one line in the output:

      Output

      Homer J. Simpson 742 Evergreen Terrace Springfield

      Using the newline character (n), you can create a true multi-line string:

      const address="Homer J. Simpsonn" + 
        '742 Evergreen Terracen' + 
        'Springfield'
      

      When logged to the console, this will display the following:

      Output

      Homer J. Simpson 742 Evergreen Terrace Springfield

      Using newline characters to designate multi-line strings can be counterintuitive, however. In contrast, creating a multi-line string with template literals can be much more straight-forward. There is no need to concatenate, use newline characters, or use backslashes. Just pressing ENTER and writing the string across multiple lines works by default:

      const address = `Homer J. Simpson
      742 Evergreen Terrace
      Springfield`
      

      The output of logging this to the console is the same as the input:

      Output

      Homer J. Simpson 742 Evergreen Terrace Springfield

      Any indentation will be preserved, so it’s important not to indent any additional lines in the string if that is not desired. For example, consider the following:

      const address = `Homer J. Simpson
                       742 Evergreen Terrace
                       Springfield`
      

      Although this style of writing the line might make the code more human readable, the output will not be:

      Output

      Homer J. Simpson 742 Evergreen Terrace Springfield

      With multi-line strings now covered, the next section will deal with how expressions are interpolated into their values with the different string declarations.

      Expression Interpolation

      In strings before ES6, concatenation was used to create a dynamic string with variables or expressions:

      const method = 'concatenation'
      const dynamicString = 'This string is using ' + method + '.'
      

      When logged to the console, this will yield the following:

      Output

      This string is using concatenation.

      With template literals, an expression can be embedded in a placeholder. A placeholder is represented by ${}, with anything within the curly brackets treated as JavaScript and anything outside the brackets treated as a string:

      const method = 'interpolation'
      const dynamicString = `This string is using ${method}.`
      

      When dynamicString is logged to the console, the console will show the following:

      Output

      This string is using interpolation.

      One common example of embedding values in a string might be for creating dynamic URLs. With concatenation, this can be cumbersome. For example, the following declares a function to generate an OAuth access string:

      function createOAuthString(host, clientId, scope) {
        return host + '/login/oauth/authorize?client_id=' + clientId + '&scope=" + scope
      }
      
      createOAuthString("https://github.com', 'abc123', 'repo,user')
      

      Logging this function will yield the following URL to the console:

      Output

      https://github.com/login/oauth/authorize?client_id=abc123&scope=repo,user

      Using string interpolation, you no longer have to keep track of opening and closing strings and concatenation operator placement. Here is the same example with template literals:

      function createOAuthString(host, clientId, scope) {
        return `${host}/login/oauth/authorize?client_id=${clientId}&scope=${scope}`
      }
      
      createOAuthString('https://github.com', 'abc123', 'repo,user')
      

      This will have the same output as the concatenation example:

      Output

      https://github.com/login/oauth/authorize?client_id=abc123&scope=repo,user

      You can also use the trim() method on a template literal to remove any whitespace at the beginning or end of the string. For example, the following uses an arrow function to create an HTML <li> element with a customized link:

      const menuItem = (url, link) =>
        `
      <li>
        <a href="https://www.digitalocean.com/${url}">${link}</a>
      </li>
      `.trim()
      
      menuItem('https://google.com', 'Google')
      

      The result will be trimmed of all the whitespace, ensuring that the element will be rendered correctly:

      Output

      <li> <a href="https://google.com">Google</a> </li>

      Entire expressions can be interpolated, not just variables, such as in this example of the sum of two numbers:

      const sum = (x, y) => x + y
      const x = 5
      const y = 100
      const string = `The sum of ${x} and ${y} is ${sum(x, y)}.`
      
      console.log(string)
      

      This code defines the sum function and the variables x and y, then uses both the function and the variables in a string. The logged result will show the following:

      Output

      The sum of 5 and 100 is 105.

      This can be particularly useful with ternary operators, which allow conditionals within a string:

      const age = 19
      const message = `You can ${age < 21 ? 'not' : ''} view this page`
      console.log(message)
      

      The logged message here will change depnding on whether the value of age is over or under 21. Since it is 19 in this example, the following output will be logged:

      Output

      You can not view this page

      Now you have an idea of how template literals can be useful when used to interpolate expressions. The next section will take this a step further by examining tagged template literals to work with the expressions passed into placeholders.

      Tagged Template Literals

      An advanced feature of template literals is the use of tagged template literals, sometimes referred to as template tags. A tagged template starts with a tag function that parses a template literal, allowing you more control over manipulating and returning a dynamic string.

      In this example, you’ll create a tag function to use as the function operating on a tagged template. The string literals are the first parameter of the function, named strings here, and any expressions interpolated into the string are packed into the second parameter using rest parameters. You can console out the parameter to see what they will contain:

      function tag(strings, ...expressions) {
        console.log(strings)
        console.log(expressions)
      }
      

      Use the tag function as the tagged template function and parse the string as follows:

      const string = tag`This is a string with ${true} and ${false} and ${100} interpolated inside.`
      

      Since you’re console logging strings and expressions, this will be the output:

      Output

      (4) ["This is a string with ", " and ", " and ", " interpolated inside." (3) [true, false, 100]

      The first parameter, strings, is an array containing all the string literals:

      • "This is a string with "
      • " and "
      • " and "
      • " interpolated inside."

      There is also a raw property available on this argument at strings.raw, which contains the strings without any escape sequences being processed. For example, /n would just be the character /n and not be escaped into a newline.

      The second parameter, ...expressions, is a rest parameter array consisting of all the expressions:

      The string literals and expressions are passed as parameters to the tagged template function tag. Note that the tagged template does not need to return a string; it can operate on those values and return any type of value. For example, we can have the function ignore everything and return null, as in this returnsNull function:

      function returnsNull(strings, ...expressions) {
        return null
      }
      
      const string = returnsNull`Does this work?`
      console.log(string)
      

      Logging the string variable will return:

      Output

      null

      An example of an action that can be performed in tagged templates is applying some change to both sides of each expression, such as if you wanted to wrap each expression in an HTML tag. Create a bold function that will add <strong> and </strong> to each expression:

      function bold(strings, ...expressions) {
        let finalString = ''
      
        // Loop through all expressions
        expressions.forEach((value, i) => {
          finalString += `${strings[i]}<strong>${value}</strong>`
        })
      
        // Add the last string literal
        finalString += strings[strings.length - 1]
      
        return finalString
      }
      
      const string = bold`This is a string with ${true} and ${false} and ${100} interpolated inside.`
      
      console.log(string)
      

      This code uses the forEach method to loop over the expressions array and add the bolding element:

      Output

      This is a string with <strong>true</strong> and <strong>false</strong> and <strong>100</strong> interpolated inside.

      There are a few examples of tagged template literals in popular JavaScript libraries. The graphql-tag library uses the gql tagged template to parse GraphQL query strings into the abstract syntax tree (AST) that GraphQL understands:

      import gql from 'graphql-tag'
      
      // A query to retrieve the first and last name from user 5
      const query = gql`
        {
          user(id: 5) {
            firstName
            lastName
          }
        }
      `
      

      Another library that uses tagged template functions is styled-components, which allows you to create new React components from regular DOM elements and apply additional CSS styles to them:

      import styled from 'styled-components'
      
      const Button = styled.button`
        color: magenta;
      `
      
      // <Button> can now be used as a custom component
      

      You can also use the built-in String.raw method on tagged template literals to prevent any escape sequences from being processed:

      const rawString = String.raw`I want to write /n without it being escaped.`
      console.log(rawString)
      

      This will log the following:

      Output

      I want to write /n without it being escaped.

      Conclusion

      In this article, you reviewed single- and double-quoted string literals and you learned about template literals and tagged template literals. Template literals make a lot of common string tasks simpler by interpolating expressions in strings and creating multi-line strings without any concatenation or escaping. Template tags are also a useful advanced feature of template literals that many popular libraries have used, such as GraphQL and styled-components.

      To learn more about strings in JavaScript, read How To Work with Strings in JavaScript and How To Index, Split, and Manipulate Strings in JavaScript.



      Source link

      How to Design a Website Without Knowing How to Code


      As a small business owner, the importance of owning a website cannot be overstated. When you’re just starting out, however, you may not have the funds to hire a web designer. So the task falls to you or your team instead.

      The good news is that you can build a website yourself without getting bogged down with any technical details. Using WP Website Builder, DreamHost’s suite of premium tools and plugins, you can quickly set up a professional, easily-customizable website — no coding knowledge required!

      In this post, we’ll walk you through setting up a basic hosting plan with WordPress and WP Website Builder pre-installed, which you can use to create a responsive website from scratch. Let’s get to work!

      We’ve Got the Ultimate Web Design Tool

      When you partner with DreamHost, you get access to WP Website Builder and more than 200+ industry-specific starter sites for free!

      An Introduction to WP Website Builder

      The landing page for WP Website Builder.

      It can be challenging to design a unique, fully-functional website from scratch. Going the traditional route requires you to learn, at the very least, web design languages like HTML and CSS. You also need to consider responsiveness across different devices, cross-browser compatibility, and accessibility for different types of users.

      Enter WP Website Builder!

      Built by our friends at BoldGrid, WP Website Builder is a drag-and-drop tool for creating websites with minimal effort. You’ll get access to a huge selection of professional website templates, making it simple to create a unique-looking site and publish your content quickly. And while you don’t need any coding skills to use WP Website Builder, you’ll be able to scale up your site’s functionality over time because it’s built with WordPress, the world’s most popular content management system (CMS).

      Best of all, as a DreamHost user, you get access to WP Website Builder for free! All you need is one of our Shared or DreamPress plans.

      How to Design a Website Without Knowing How to Code (In 6 Steps)

      So how can you get started with your new site? The following six steps will take you from purchasing a hosting plan all the way through building a website.

      Step 1: Create a DreamHost account

      Shared hosting plans come cheap and are perfect for getting your small business off the ground. You get a user-friendly interface with a no-stress one-click installer and the flexibility to build any kind of website: whether that’s an e-commerce store, a business website, or a blog.

      For new website owners, we’d suggest starting out with either a Shared Starter or Shared Unlimited plan. On the checkout page, tick the checkboxes shown below, either under the Additional Options section or in the right-hand menu, to pre-install WordPress and include WP Website Builder.

      The checkout page for the DreamHost Shared Unlimited plan.

      If you already have an account, you can access your DreamHost control panel to add WP Website Builder to an existing WordPress installation instead.

      Step 2: Access Your Website and Choose a Theme

      At this point, you’ll want to log in to your new WordPress website. You’ll be presented with the BoldGrid Inspirations wizard, which will walk you through much of the setup process. Click on the Let’s Get Started button to begin.

      The WP Website Builder BoldGrid Inspirations wizard.

      Next, you’ll want to choose a theme for your website. This will provide a starting point and help to determine your content’s appearance and layout.

      The Inspiration wizard theme selection screen.

      Hover over any theme to see it more closely, and click on the Select button to apply it to your site. We’ll go ahead and select the Cobalt theme. Keep in mind that you can always change your theme later, and you’ll also be able to customize many of its elements and styles.

      Step 3: Choose Your Content Structure

      Once you’ve selected a theme, the next thing to do is choose a content structure. Click on the Change Content button to begin.

      The Inspiration wizard Content screen.

      You’re given three Pageset options: Base, Five Page, and Kitchen Sink. You can also choose whether or not your website will have a blog.

      Adding a blog to your site.

      The Content screen also lets you see how responsive your website will be across different screen sizes. That way, you’ll know what it will look like for both desktop and mobile users.

      Step 4: Enter Essential Site Information

      This next screen lets you fill in information that will be used to populate key aspects of your website, such as your contact information and social media account details. You can also leave this screen as-is and edit these details later.

      The Inspiration wizard Essentials screen.

      Once you’re done here, select the Finish and Install button to complete the installation.

      Step 5: Design Your Pages and Posts With the Drag-and-Drop Builder

      After the installation is complete, you’ll be presented with your WordPress dashboard. The next step is to begin customizing your website by adding new pages and posts (if your site includes a blog).

      The WordPress dashboard.

      We’ll start by adding a new page called Documentation and include some content on the page using blocks.

      The Add New Page screen.

      The next screen is divided into two sections. The right-hand side of the page gives you a selection of blocks, and the left shows you a preview of what your page will look like once it’s live.

      Hover over an appropriate block and click the + Add to Page button.

      The Add New Page screen.

      Here’s what our page looks like once a few blocks have been added.

      A new page with multiple content blocks.

      Once you’re satisfied with a block, select the checkmark icon to accept it. 

      Step 6: Customize Your Blocks and Publish Your Content

      After adding a block, you’ll be taken back to the main editing screen. This is where you can edit the blocks you added or include entirely new content.

      The Add New Page screen.

      When you’re done editing, preview your page to make sure you’re satisfied with the look, and then select the Publish button to make it live.

      Publishing a new page.

      If you chose to include a blog on your website earlier, you can create posts just as easily now. Click on the Add New link that appears when you hover over the Post menu.

      Creating a new post.

      You can then create your post exactly the same way your page was designed. Clicking the + button will open a menu with different types of block options. Once you’ve created your post, preview and publish it, or save it as a draft to continue editing it later.

      Website Design Made Simple

      Whether you want to install a WordPress theme, choose a website template, or hire a web developer, we can help! Subscribe to our monthly digest so you never miss an article.

      You Can Be a Website Designer

      Building your business website from scratch should be quick and easy. Fortunately, the intuitive drag-and-drop interface of WP Website Builder and its dozens of professional WordPress themes make it a practical choice for new website owners.

      Ready to build your own website? Get started and have your WordPress site up and running in no time by signing up for one of our shared hosting plans and WP Website Builder!



      Source link