Construyendo componentes de esqueleto con React | Programar Plus

Una de las ventajas de crear una aplicación de página única (SPA) es que la navegación entre páginas es extremadamente rápida. Desafortunadamente, los datos de nuestros componentes a veces solo están disponibles después de haber navegado a una parte específica de nuestra aplicación. Podemos subir de nivel el rendimiento percibido por el usuario dividiendo el componente en dos partes: el contenedor (que muestra una vista esquemática cuando está vacío) y el contenido. Si retrasamos la reproducción del componente de contenido hasta que hayamos recibido el contenido requerido, entonces podemos aprovechar la vista esquemática del contenedor, ¡aumentando así el tiempo de carga percibido!

Comencemos a crear nuestros componentes.

Lo que estamos haciendo

Aprovecharemos el componente de esqueleto que se creó en el artículo “Creación de pantallas de esqueleto con propiedades personalizadas de CSS”.

Este es un gran artículo que describe cómo puede crear un componente de esqueleto y el uso de la :empty selector nos permite utilizar inteligentemente {this.props.children} dentro de nuestros componentes para que la tarjeta esqueleto se represente siempre que el contenido no esté disponible.

Vea Pen React 16 – Skeleton Card – Final de Mathias Rechtzigel (@MathiasaurusRex) en CodePen.

Creando nuestros componentes

Vamos a crear un par de componentes para ayudarnos a comenzar.

  1. El contenedor exterior (CardContainer)
  2. El contenido interior (CardContent)

Primero, creemos nuestro CardContainer. Este componente contenedor aprovechará la :empty pseudo selector para que represente la vista de esqueleto siempre que este componente no reciba un hijo.

class CardContainer extends React.Component {
  render() {
    return (
      <div className="card">
        {this.props.children}
      </div>
    );
  }
}

A continuación, creemos nuestro CardContent componente, que se anidará dentro de nuestro CardContainer componente.

class CardContent extends React.Component {
  render() {
    return (
      <div className="card--content">
        <div className="card-content--top">
          <div className="card-avatar">
            <img 
              className="card-avatar--image"
              src={this.props.avatarImage}
              alt="" />
            <span>{this.props.avatarName}</span>
          </div>
        </div>
        <div className="card-content--bottom">
          <div className="card-copy">
            <h1 className="card-copy--title">{this.props.cardTitle}</h1>
            <p className="card-copy--description">{this.props.cardDescription}</p>
          </div>
          <div className="card--info">
            <span className="card-icon">
              <span className="sr-only">Total views: </span>
              {this.props.countViews}
            </span>
            <span className="card-icon">
              <span className="sr-only">Total comments: </span>
              {this.props.countComments}
            </span>
          </div>
        </div>
      </div>
    );
  }
}

Como puede ver, hay un par de espacios para las propiedades que se pueden aceptar, como una imagen y un nombre de avatar y el contenido de la tarjeta que está visible.

Poner los componentes juntos nos permite crear un componente de tarjeta completo.

<CardContainer>
  <CardContent
    avatarImage="path/to/avatar.jpg"
    avatarName="FirstName LastName"
    cardTitle="Title of card"
    cardDescription='Description of card'
    countComments="XX"
    countViews="XX"
  />
</CardContainer>

Vea Pen React 16 – Tarjeta esquelética – Contenido de la tarjeta sin estado por Mathias Rechtzigel (@MathiasaurusRex) en CodePen.

Usar un operador ternario para revelar contenido cuando se ha cargado el estado

Ahora que tenemos ambos CardContainer y CardContent componente, hemos dividido nuestra tarjeta en las piezas necesarias para crear un componente esqueleto. Pero, ¿cómo cambiamos entre los dos cuando se ha cargado el contenido?

¡Aquí es donde un uso inteligente de los operadores estatales y ternarios viene al rescate!

Vamos a hacer tres cosas en esta sección:

  1. Cree un objeto de estado que inicialmente se establece en false
  2. Actualice nuestro componente para usar un operador ternario para que el cardContent El componente no se renderizará cuando el estado sea false
  3. Establecer el estado para que sea el contenido de nuestro objeto una vez que recibamos esa información

Queremos establecer el estado predeterminado de nuestro contenido para que se establezca en false. Esto oculta el contenido de la tarjeta y permite que el CSS :empty selector para hacer su magia.

this.state = {
  cardContent: false
};

Ahora tenemos que actualizar nuestro CardContainer niños para incluir un operador ternario. En nuestro caso, mira this.state.cardContent para ver si se resuelve como verdadero o falso. Si es true, hace todo en el lado izquierdo del colon (:). Por el contrario, si es false, hace todo en la mano derecha del colon. Esto es bastante útil porque los objetos se resolverán true y si establecemos el estado inicial en false, entonces nuestro componente tiene todas las condiciones que necesita para implementar un componente de esqueleto.

Combinemos todo dentro de nuestra aplicación principal. No nos preocuparemos por el estado interior CardContent bastante todavía. Lo vincularemos a un botón para imitar el proceso de obtener contenido de una API.

<CardContainer>
  {this.state.cardContent 
    ? 
      <CardContent 
      avatarImage={this.state.cardContent.card.avatarImage}
      avatarName={this.state.cardContent.card.avatarName}
      cardTitle={this.state.cardContent.card.cardTitle}
      cardDescription={this.state.cardContent.card.cardDescription}
      countComments={this.state.cardContent.card.countComments}
      countViews={this.state.cardContent.card.countViews}/>
    : 
    null
  }          
</CardContainer>

¡Auge! Como puede ver, la tarjeta se representa como el componente esqueleto desde el estado de cardContent se establece en false. A continuación, crearemos una función que establece el estado de cardContent a un objeto de datos de tarjeta simulado (dummyCardData):

populateCardContent = (event) => {
    const dummyCardData =  {
      card: {
        avatarImage: "https://gravatar.com/avatar/f382340e55fa164f1e3aef2739919078?s=80&d=https://codepen.io/assets/avatars/user-avatar-80x80-bdcd44a3bfb9a5fd01eb8b86f9e033fa1a9897c3a15b33adfc2649a002dab1b6.png",
        avatarName: "Mathias Rechtzigel",
        cardTitle: "Minneapolis",
        cardDescription:"Winter is coming, and it will never leave",
        countComments:"52",
        countViews:"32"
      }
    }
    const cardContent = dummyCardData
    this.setState({
      cardContent
    })
  }

En este ejemplo, establecemos el estado dentro de una función. También podríamos aprovechar los métodos del ciclo de vida de React para completar el estado del componente. Tendríamos que echar un vistazo al método apropiado a utilizar, dependiendo de nuestros requisitos. Por ejemplo, si estoy cargando un componente individual y quiero obtener el contenido de la API, entonces usaríamos el método de ciclo de vida ComponentDidMount. Como dice la documentación, debemos tener cuidado de usar este método de ciclo de vida de esta manera, ya que podría causar un renderizado adicional, pero estableciendo el estado inicial en false debería evitar que eso suceda.

Vea Pen React 16 – Skeleton Card – Final de Mathias Rechtzigel (@MathiasaurusRex) en CodePen.

La segunda tarjeta de la lista está conectada al evento de clic que establece el cardContent Expresar. Una vez que el estado se establece en el objeto del contenido, la versión esqueleto de la tarjeta desaparece y se muestra el contenido, lo que garantiza que el usuario no vea un destello de la interfaz de usuario (se acerca la temporada de FLU, por lo que no queremos dar la usuarios de la gripe!).

Revisemos

Cubrimos bastante, así que recapitulemos lo que hicimos.

  1. Creamos un CardContainer. El componente contenedor está aprovechando la :empty pseudo selector para que muestre la vista de esqueleto del componente cuando está vacío.
  2. Creamos el CardContent componente que está anidado dentro CardContainer al que pasamos nuestro estado.
  3. Establecemos el estado predeterminado del cardContent a false
  4. Usamos un operador ternario para representar el componente de contenido interno solo cuando recibimos el contenido y lo colocamos en nuestro cardContent objeto de estado.

¡Y ahí lo tenemos! Un aumento percibido en el rendimiento al crear un estado intersticial entre la interfaz de usuario que se representa y la que recibe los datos para completar el contenido.

(Visited 5 times, 1 visits today)