Naučte se React praxí a vytvořte úžasnou galerii obrázků

Jedním z nejlepších způsobů, jak se naučit React, je praxe. Nic vám nepomůže učit se tak, jako pokusy a omyly. Když si zašpiníte ruce, váš mozek je jako houba. Vaše schopnost vstřebávat nové poznatky je neuvěřitelná. Učení praxí je navíc také zábavnější. Z tohoto důvodu jsem se rozhodl napsat tento krátký návod na React. Doufám, že vám to pomůže naučit se React a zlepšit své dovednosti. Jako vždy jsem vložil odkazy na demo na CodePen a repozitář na GitHubu.

Živá ukázka na CodePen.

Zdrojový kód na GitHubu.

Rychlý úvod

Je to už nějakou dobu, co jsme si procvičovali kódování na nějakém tutoriálu. Ve skutečnosti se poslední tutoriál objevil na tomto blogu 30. září. Také je náhoda, že poslední tutoriál byl o Reactu. Dnes vám pomůžu naučit se React a ještě více procvičit své dovednosti. V tomto tutoriálu vytvoříme úžasnou galerii obrázků. Kromě toho bude tato galerie obsahovat také modální dialog pro náhled větší verze obrázků. Tato galerie bude vyžadovat řadu zdrojů. Užijte si tento tutoriál.

Skládání zdrojů

První věc, kterou musíme udělat, abychom vybudovali galerii a naučili se React, je shromáždit potřebné zdroje. Začněme s externími šablonami stylů CSS. V tomto tutoriálu budeme používat tři šablony stylů CSS. Jsou to normalize, bootstrap 3 a font úžasné. Cílem normalizace šablony stylů je držet se osvědčených postupů CSS. Stručně řečeno, různé prohlížeče vykreslují různé prvky jiným způsobem. Chceme tyto nekonzistence prohlížeče omezit. V důsledku toho vytvoříme konzistentní prostředí napříč prohlížeči.

Stylesheet z rámce Bootstrap poskytne tento tutoriál se systémem mřížky. Použijeme jej k distribuci obrázků v naší galerii. I když bychom mohli napsat nějaký jednoduchý mřížkový systém. To by nás však stálo nějaký čas, který můžeme využít moudřeji. Jaký je důvod implementace poslední šablony stylů Font awesome? V tomto tutoriálu chci použít dvě ikony. První ikonu použijeme jako popisek pro otevření modálního okna. Toto bude ikona „rozbalit“. Poté použijeme ikonu „times“ jako štítek pro uzavření modálu. To je vše pro CSS.

A co JavaScript? Budeme potřebovat dvě knihovny, abychom vytvořili tento tutoriál o tom, jak se naučit React by praxí fungovat. Tyto dvě knihovny jsou React a ReactDOM. To je vše. Nebudeme používat jQuery ani jinou knihovnu. Jedna věc o JavaScriptu. Budu používat syntaxi ES6. Proto je vysoce pravděpodobné, že budete potřebovat nějaký kompilátor, který převede kód do starší syntaxe JavaScriptu. Jinak to ve starším prohlížeči asi nepůjde. V tomto tutoriálu jsem použil babel.

Rychlá poznámka:Bootstrap framework již obsahuje šablonu stylů normalizace. Obsahuje však mnohem starší verzi. Proto jsem také použil externí verzi. Nechci čekat, až Bootstrap implementuje nejnovější verzi. Také si myslím, že neuškodí, když použijeme dva normalizační styly. V nejhorším případě můžeme vždy odstranit sekundární šablonu stylů a použít tu v Bootstrapu. Jinými slovy, nemáme se čeho bát.

HTML a položení základů

Dobře, máme všechny potřebné zdroje. To byl první krok na naší cestě naučit se reagovat praxí. Druhým krokem je vytvoření HTML dokumentu a přidání struktury pro tento tutoriál. Protože většina kódu bude v JavaScriptu (React), bude tento krok velmi rychlý. Nejprve musíme přidat tři výše uvedené šablony stylů CSS do head části dokumentu. Potom musíme do těla přidat dvě knihovny React sekce. Také vytvoříme kontejner pro naši galerii.

Tento kontejner bude sekcí prvek s třídou „galerie-kontejner“. Proč potřebujeme tento kontejner? React potřebuje nějaké místo, kde vykreslí své komponenty. Tato sekce bude toto místo. To je vše, co budeme z hlediska HTML potřebovat.

HTML:

<!DOCTYPE html>
<html >
 <head>
  <meta charset="UTF-8">
  <title>How to Learn React and Create Stunning Image Gallery</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
 
  <!-- Normalize stylesheet -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">

  <!-- Bootstrap 3 -->
  <link rel='stylesheet prefetch' href='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css'>

  <!-- Font Libre Franklin -->
  <link rel='stylesheet prefetch' href='https://fonts.googleapis.com/css?family=Libre+Franklin:300,400,700'>

  <!-- Main stylesheet-->
  <link rel="stylesheet" href="css/style.css">
 </head>

 <body>
  <section class="gallery-container"></section>

  <!-- Scripts -->
  <script src='https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react.min.js'></script>

  <script src='https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react-dom.min.js'></script>

  <script src="js/index.js"></script>
 </body>
</html>

Sass a některé proměnné pro začátek

Pojďme ke třetímu kroku na naší cestě naučit se reagovat praxí. Chceme, aby galerie nejen fungovala. Chceme také, aby to vypadalo skvěle. Proto vytvoříme několik stylů. Abychom usnadnili styling, vytvoříme řadu znovu použitelných proměnných. První proměnná bude pro černou barvu (č. 111). Druhý bude pro poloměr okraje (4px). Poslední proměnná bude pro přechod (všechny 0,25s easy-in-out).

Sass:

// Variables
$black: #111;
$radius: 4px;
$transition: all .25s ease-in-out;

Základní informace

Dalším krokem je provést nějakou úpravu stylu pro html a tělo Prvky. Cílem tohoto výukového programu React by practice je vytvoření galerie obrázků. Vzhledem k tomu, že bude používat modal s překrytím, měli bychom se ujistit, že budeme mít dostatek nemovitostí. Jinými slovy, udělejme galerii v plné výšce. To bude vyžadovat nastavení výšky a minimální výška vlastnosti html a tělo na „100 %“. Změníme také nastavení pro typografii. Jinými slovy, nastavíme „16px“ jako velikost písma pro html . Dále nastavíme „100 %“ jako velikost písma pro body . Tím se změní výchozí nastavení Bootstrapu.

Sass:

html,
body {
 min-height: 100%;
 height: 100%;
}

html {
 font-size: 16px;
}

body {
 position: relative;
 font-size: 100%;
}

Styl kontejneru galerie

Pravděpodobně jste si všimli, že jsme také nastavili pozici prvku těla na „relativní“. To se bude hodit později k překrytí pozice pro modální. Nyní se budeme zabývat styly pro hlavní část tohoto výukového programu React by practice. Přidáme mezery mezi obsahem galerie a kontejnerem. Můžeme to udělat přidáním nějaké vycpávky , řekněme 0,9375rem.

Sass:

.gallery-container {
 padding-top: .9375rem;
}

Péče o karty galerie

Dále se postaráme o karty galerie. Nastavíme pozici všech karet na „relativní“ hodnotu. Pamatujete si ikonu pro otevření modálního okna? Tato ikona bude umístěna absolutně. Proto potřebujeme nějakou sadu kontejnerů umístěnou relativně jako první. Jinak by byla ikona umístěna vzhledem k oknu prohlížeče. Tohle je něco, čemu se chceme vyhnout. Poté nastavíme přetečení na „skryté“. To asi není nutné. Je to jen pro jistotu. Nakonec přidáme margin-botto m . Tím se vytvoří určitý prostor mezi kartami.

Sass:

.gallery-card {
 position: relative;
 overflow: hidden;
 margin-bottom: 1.875rem;
}

Styly pro náhledy galerie (karty) budou velmi snadné. Budeme muset nastavit max-width na „100 %“. To nám pomůže zabránit překrývání obrázků. Také, aby poměr obrázků zůstal nedotčený, nastavíme výšku na auto. Nakonec udělejme rohy mírně zaoblené nastavením poloměru okraje do našeho poloměru $ proměnná.

Sass:

.gallery-thumbnail {
 max-width: 100%;
 height: auto;
 border-radius: $radius;
}

Styl ikon karet

Další věcí na řadě v tomto tutoriálu React by practice je ikona karty. Tato ikona umožní uživatelům otevřít modální dialog. Jak jsem již zmínil, použijeme ikonu „rozbalit“ z Font Awesome. Rozhodl jsem se umístit ikonu přímo doprostřed miniatury. Můžete buď následovat mé kroky, nebo jej umístit kamkoli chcete. K tomu použijeme kombinaci pozice , nahoře , doleva a transformovat vlastnosti. Potom zvětšíme jeho velikost písma , nastavte jeho barvu na bílou (#fff) a změňte kurzor na ukazatel .

Také nastavíme zobrazení na „ blok“ a neprůhlednost na „0“. V důsledku toho bude ikona zpočátku skrytá. Když uživatel najede na kartu, ikona se sama zobrazí. Provedeme to změnou neprůhlednosti na „1“. Aby byla tato změna plynulejší, použijeme přechod a $transition variabilní. Také když uživatel najede myší na ikonu, změní se její barva do černé.

Sass:

.card-icon-open {
 display: block;
 position: absolute;
 top: 50%;
 left: 50%;
 font-size: 2rem;
 color: #fff;
 cursor: pointer;
 opacity: 0;
 transform: translate(-50%, -50%);
 transition: $transition;
 
 &:focus,
 &:hover {
  color: $black;
 }
}

.gallery-thumbnail:focus ~ .card-icon-open,
.gallery-thumbnail:hover ~ .card-icon-open,
.gallery-thumbnail ~ .card-icon-open:focus,
.gallery-thumbnail ~ .card-icon-open:hover {
 opacity: 1;
}

Dokončení s překryvnou vrstvou

Je čas na poslední část Sass části tohoto výukového programu React by practice. To znamená stylování modálního překrytí a modálního dialogu. Nejprve nastavíme pozici překrytí na „absolutní“. Poté nastavíme top a doleva vlastnosti na „0“, abyste zajistili, že překrytí bude začínat v levém horním rohu. Nastavení šířky a výška na „100 %“ nám pomůže pokrýt celou obrazovku. Z-index nastavení na „10“ přesune překrytí do popředí. Nakonec nastavíme pozadí na poloprůhledné světle černé.

Sass:

.modal-overlay {
 position: absolute;
 top: 0;
 left: 0;
 z-index: 10;
 width: 100%;
 height: 100%;
 background: rgba(21,21,21,.75);
}

V případě modálního těla použijeme stejné kombo, jaké jsme použili k umístění ikony „rozbalit“. Jinými slovy, nastavíme pozici na „absolutní“, nahoře a doleva na „50 %“ a transformovat na „přeložit (-50 %, -50 %)“. Z-index modal-body bude jen o něco vyšší než z-index překrytí. Jinak by to překryv překryl také. Znovu pro jistotu nastavte přetečení na „skryté“. Protože Bootstrap předdefinoval výplň , budeme jej muset resetovat nastavením na „0“. Aby byly rohy modálního těla mírně zaoblené, nastavíme poloměr okraje na poloměr $ .

Sass:

.modal-body {
 position: absolute;
 top: 50%;
 left: 50%;
 z-index: 11;
 padding: 0;
 overflow: auto;
 border-radius: $radius;
 transform: translate(-50%, -50%);
}

Je čas upravit styl zavírací modální dialogové ikony. Toto je poslední věc týkající se sass v tomto výukovém programu React by practice. Nastavte jeho polohu na „absolutní“, nahoře na „0“ a doprava na „8px“. Dále nastavte velikost písma na „1,5rem“, aby bylo klikání snazší. Poté nastavte barvu do $černé a po najetí myší na „#fff“. Použijme také přechod aby tato změna byla hladší.

Sass:

.modal-close {
 position: absolute;
 top: 0;
 right: 8px;
 font-size: 1.5rem;
 color: $black;
 transition: $transition;
 
 &:focus,
 &:hover {
  color: #fff;
 }
}

Celý Sass:

$black: #111;
$radius: 4px;
$transition: all .25s ease-in-out;

html,
body {
 min-height: 100%;
 height: 100%;
}

html {
 font-size: 16px;
}

body {
 position: relative;
 font-size: 100%;
}

.gallery-container {
 padding-top: .9375rem;
}

.gallery-card {
 position: relative;
 overflow: hidden;
 margin-bottom: 1.875rem;
}

.gallery-thumbnail {
 max-width: 100%;
 height: auto;
 border-radius: $radius;
}

.card-icon-open {
 display: block;
 position: absolute;
 top: 50%;
 left: 50%;
 font-size: 2rem;
 color: #fff;
 cursor: pointer;
 opacity: 0;
 transform: translate(-50%, -50%);
 transition: $transition;
 
 &:focus,
 &:hover {
  color: $black;
 }
}

.gallery-thumbnail:focus ~ .card-icon-open,
.gallery-thumbnail:hover ~ .card-icon-open,
.gallery-thumbnail ~ .card-icon-open:focus,
.gallery-thumbnail ~ .card-icon-open:hover {
 opacity: 1;
}

.modal-overlay {
 position: absolute;
 top: 0;
 left: 0;
 z-index: 10;
 width: 100%;
 height: 100%;
 background: rgba(21,21,21,.75);
}

.modal-body {
 position: absolute;
 top: 50%;
 left: 50%;
 z-index: 11;
 padding: 0;
 overflow: auto;
 border-radius: $radius;
 transform: translate(-50%, -50%);
}

.modal-close {
 position: absolute;
 top: 0;
 right: 8px;
 font-size: 1.5rem;
 color: $black;
 transition: $transition;
 
 &:focus,
 &:hover {
  color: #fff;
 }
}

JavaScript a špiníme si ruce

HTML a Sass jsou za námi. Nyní se musíme vypořádat s hlavní částí tohoto výukového programu React by practice. První dva kroky budou uložení kontejneru galerie do proměnné. Protože se tento kontejner pravděpodobně nezmění, můžeme použít const klíčové slovo. Dále vytvořte pole pro adresy URL pro naše obrázky. Některé z těchto adres URL možná budete chtít v budoucnu změnit. Proto raději použijeme let klíčové slovo.

JavaScript:

// Cache gallery container
const galleryContainer = document.querySelector('.react-gallery');

// Create new array with URLs for images
let imgUrls = [
 'https://source.unsplash.com/3Z70SDuYs5g/800x600',
 'https://source.unsplash.com/01vFmYAOqQ0/800x600',
 'https://source.unsplash.com/2Bjq3A7rGn4/800x600',
 'https://source.unsplash.com/t20pc32VbrU/800x600',
 'https://source.unsplash.com/pHANr-CpbYM/800x600',
 'https://source.unsplash.com/3PmwYw2uErY/800x600',
 'https://source.unsplash.com/uOi3lg8fGl4/800x600',
 'https://source.unsplash.com/CwkiN6_qpDI/800x600',
 'https://source.unsplash.com/9O1oQ9SzQZQ/800x600',
 'https://source.unsplash.com/E4944K_4SvI/800x600',
 'https://source.unsplash.com/-hI5dX2ObAs/800x600',
 'https://source.unsplash.com/vZlTg_McCDo/800x600'
];

Vytvoření nezbytných komponent

Naším dalším krokem v tomto výukovém programu React by practice je vytvoření komponent React. Použijeme tři komponenty:GalleryImage, GalleryModal a Gallery. Komponenta GalleryImage generuje img prvky a je to nejjednodušší. Tato komponenta bude mít className , src a alt atributy. Všechny tyto atributy budou nastaveny na stejné rekvizity .

JavaScript:

// Component for gallery image
class GalleryImage extends React.Component {
 render() {
  return(
   <img className={this.props.className} src={this.props.src} alt={this.props.alt} />
  )
 }
}

Druhou komponentou je GalleryModal. Tato komponenta bude obsahovat dva div prvky, kotva tag a img . První div bude pro modal-overlay, zatímco druhý on bude pro modal-body. Značka Anchor bude používat ikonu „krát“ z písma Awesome a umožní uživateli zavřít překrytí. Nakonec je obrázek pro náhled. Kromě toho použijeme if příkaz ke kontrole, zda má být modal viditelný nebo ne. Pokud ne, vrátíme null . To zablokuje React ve vykreslování komponenty.

JavaScript:

// Component for gallery modal
class GalleryModal extends React.Component {
 render() {
  if (this.props.isOpen === false) {
   return null;
  }
 
  return(
   <div isOpen={this.props.isOpen} className='modal-overlay' onClick={this.props.onClick} name={this.props.name}>
    <div className='modal-body'>
     <a className='modal-close' href='#' onClick={this.props.onClick}><span className='fa fa-times'></span></a>
 
     <img src={this.props.src} />
    </div>
   </div>
  )
 }
}

Třetí a poslední součástí tohoto výukového programu React by practice je Galerie. Je také nejsložitější. Tato komponenta bude obsahovat constructor() a super() . Pokud si nejste jisti, jak tyto metody fungují, podívejte se na tento tutoriál formuláře React. Dozvíte se přesně, kdy a proč tyto metody používat. V této komponentě také vytvoříme počáteční stav této galerie. Bude obsahovat dvě položky:showModal a url . Bylo by zajímavé pohovořit o tom, jak se naučit React by cvičným tutoriálem a ignorovat stavy.

Pro zpracování modálního dialogu vytvoříme openModal a zavřít Modální metody. Potom tyto metody také svážeme v konstruktoru aby byly přístupné pro komponenty. Obě metody změní stav galerie. openModal nastaví showModal na „true“ a url na adresu URL aktuálního obrázku. zavřít Modální nastaví showModal na „false“ a resetujte url .

JavaScript:

// Component for gallery
class Gallery extends React.Component{
 constructor(props) {
  super(props);
 
  this.state = {
   showModal: false,
   url: ''
  }
 
  this.openModal = this.openModal.bind(this);
 
  this.closeModal = this.closeModal.bind(this);
 }
 
 render() {
  return(
   <div refs='gallery-container' className='container-fluid gallery-container'>
    <div className='row'>
     {
      imgUrls.map((url, index) => {
       return <div className='col-sm-6 col-md-3 col-xl-2'>
        <div className='gallery-card'>
         <GalleryImage className='gallery-thumbnail' src={url} alt={'Image number ' + (index + 1)} />
 
         <span className='card-icon-open fa fa-expand' value={url} onClick={(e) => this.openModal(url, e)}></span>
        </div>
      </div>
     })
    }
   </div>
 
   <GalleryModal isOpen={this.state.showModal} onClick={this.closeModal} src={this.state.url} /> 
  </div>
  )
 }

 // Function for opening modal dialog
 openModal(url, e) {
  this.setState({
   showModal: true,
   url: url
  })
 };

 // Function for closing modal dialog
 closeModal() {
  this.setState({
   showModal: false,
   url: ''
  })
 }
}

Posledním posledním krokem k tomu, aby se tato výuková práce React by practice naučila, je vykreslení komponenty Gallery.

JavaScript:

// Let's render the whole thing
ReactDOM.render(
 <Gallery imgUrls={imgUrls} />
, galleryContainer);

Celý JavaScript:

// Cache gallery container
const galleryContainer = document.querySelector('.react-gallery');

// Create new array with URLs for images
let imgUrls = [
 'https://source.unsplash.com/3Z70SDuYs5g/800x600',
 'https://source.unsplash.com/01vFmYAOqQ0/800x600',
 'https://source.unsplash.com/2Bjq3A7rGn4/800x600',
 'https://source.unsplash.com/t20pc32VbrU/800x600',
 'https://source.unsplash.com/pHANr-CpbYM/800x600',
 'https://source.unsplash.com/3PmwYw2uErY/800x600',
 'https://source.unsplash.com/uOi3lg8fGl4/800x600',
 'https://source.unsplash.com/CwkiN6_qpDI/800x600',
 'https://source.unsplash.com/9O1oQ9SzQZQ/800x600',
 'https://source.unsplash.com/E4944K_4SvI/800x600',
 'https://source.unsplash.com/-hI5dX2ObAs/800x600',
 'https://source.unsplash.com/vZlTg_McCDo/800x600'
];

// Component for gallery image
class GalleryImage extends React.Component {
 render() {
  return(
   <img className={this.props.className} src={this.props.src} alt={this.props.alt} />
  )
 }
}

// Component for gallery modal
class GalleryModal extends React.Component {
 render() {
  if (this.props.isOpen === false) {
   return null;
  }
 
  return(
   <div isOpen={this.props.isOpen} className='modal-overlay' onClick={this.props.onClick} name={this.props.name}>
    <div className='modal-body'>
     <a className='modal-close' href='#' onClick={this.props.onClick}><span className='fa fa-times'></span></a>
 
     <img src={this.props.src} />
    </div>
   </div>
  )
 }
}

// Component for gallery
class Gallery extends React.Component{
 constructor(props) {
  super(props);
 
  this.state = {
   showModal: false,
   url: ''
  }
 
  this.openModal = this.openModal.bind(this);
 
  this.closeModal = this.closeModal.bind(this);
 }
 
 render() {
  return(
   <div refs='gallery-container' className='container-fluid gallery-container'>
   <div className='row'>
    {
     imgUrls.map((url, index) => {
      return <div className='col-sm-6 col-md-3 col-xl-2'>
       <div className='gallery-card'>
        <GalleryImage className='gallery-thumbnail' src={url} alt={'Image number ' + (index + 1)} />
 
        <span className='card-icon-open fa fa-expand' value={url} onClick={(e) => this.openModal(url, e)}></span>
       </div>
      </div>
     })
    }
   </div>
 
   <GalleryModal isOpen={this.state.showModal} onClick={this.closeModal} src={this.state.url} /> 
  </div>
  )
 }
 
 // Function for opening modal dialog
 openModal(url, e) {
  this.setState({
   showModal: true,
   url: url
  })
 };

 // Function for closing modal dialog
 closeModal() {
  this.setState({
    showModal: false,
    url: ''
  })
 }
}

// Let's render the whole thing
ReactDOM.render(
 <Gallery imgUrls={imgUrls} />
, galleryContainer);

Závěrečné úvahy o tom, jak se naučit reagovat praxí

Gratulujeme, opět jste to zvládli! Dokončili jste tento výukový program React by practice. Nejen, že jste se dozvěděli něco o Reactu a procvičili si své dovednosti. Vytvořili jste také jednoduchou fotogalerii s modálním dialogem. Nezapomeňme také zmínit, že jste si procvičili moderní syntaxi JavaScriptu. Jinými slovy, odvedli jste skvělou práci. Měl bys být na sebe hrdý. Nyní, jaký je další projekt, který použijete k procvičení svých znalostí React? Pamatujte, že učení se nikdy nekončí.