Как устроен React (на примере статьи про эпидемию)

Недав­но у нас вышел пере­вод ста­тьи про рас­про­стра­не­ние эпи­де­мий. Там инте­рес­но: сре­ди обыч­но­го тек­ста выво­дят­ся интер­ак­тив­ные видже­ты с симу­ля­ци­я­ми. И если посмот­реть под капот, мы уви­дим, что эти симу­ля­ции сде­ла­ны очень эле­гант­но и понят­но. Напри­мер, вот неболь­шой фраг­мент про изле­че­ние людей:

<div>
  <h3>Излечение</h3>
</div>
<div>
  Люди со временем излечиваются. Предположим, через два шага симуляции (то есть через два дня) люди поправляются:
</div>
<Figure>
  <Grid 
    daysIncubating={0} 
    daysSymptomatic={2} 
    gridRows={9} 
    gridCols={9} 
    nodeSize={30} 
    nug={1} 
    randomSeed={100}
    personHours={4} 
    showInteractions={false}
    speed={0.4} 
    transmissionProbability={1}
    travelRadius={1}
  />
</Figure>

Вид­но, что обыч­ный текст с заго­лов­ком сде­лан как в HTML, а интер­ак­тив­ный виджет сде­лан каким-то очень понят­ным, эле­гант­ным кодом. Давай­те посмот­рим, что это за код.

Это React.js

Глав­ное блю­до это­го про­ек­та — систе­ма React.js. Это биб­лио­те­ка для созда­ния поль­зо­ва­тель­ских интер­фей­сов и рабо­ты со страницей.

В нашем про­ек­те React нужен для трёх вещей:

  • По-разному выде­лять в тек­сте ста­тьи зара­жён­ных, боль­ных и излечившихся.
  • Рабо­тать со слай­де­ра­ми и симуляцией.
  • Встра­и­вать симу­ля­цию пря­мо в текст статьи.

В React парал­лель­но про­ис­хо­дят два про­цес­са. С одной сто­ро­ны, раз­ра­бот­чик подроб­но опи­сы­ва­ет эле­мен­ты интер­фей­са: какой долж­на быть кноп­ка или пункт меню; как они долж­ны себя вести; как выгля­деть. Эти опи­са­ния упа­ко­вы­ва­ют­ся в «ком­по­нен­ты» — такие модуль­ные куби­ки, из кото­рых мож­но соби­рать интер­фейс. Кубик может быть стан­дарт­ным и автор­ским, слож­ным и про­стым. Мож­но заим­ство­вать чужие куби­ки. Мож­но вкла­ды­вать кубик в кубик и делать мегакубики.

С дру­гой сто­ро­ны, раз­ра­бот­чик исполь­зу­ет про­стые коман­ды в самом коде про­грам­мы, что­бы рас­ска­зать, где какие куби­ки использовать.

Сила React

Сила React в том, что в нём есть два мира — «Что где сто­ит» и «Что как рабо­та­ет». И эти миры доста­точ­но хоро­шо раз­де­ле­ны, что­бы не ломать­ся, если что-то где-то изменилось.

Для срав­не­ния. Если у тебя обыч­ный HTML и тебе нуж­но поста­вить ссыл­ку, ты гово­ришь такое заклинание:

<a href="адрес_ссылки" target="где_откроется" class="как_выглядит">текст ссылки</a>

В этом опи­са­нии одно­вре­мен­но и «где ссыл­ка», и «как она рабо­та­ет». Если мне нуж­но 30 таких ссы­лок на стра­ни­це, мне нуж­но будет повто­рить этот код 30 раз. Каж­дый раз, когда я исполь­зую этот код, я с нуля гово­рю бра­у­зе­ру: «Так, мы с тобой сей­час будем делать ссыл­ку, давай я тебе рас­ска­жу, как она будет работать».

А что если у меня в интер­фей­се нуж­но что-то более слож­ное, чем ссыл­ка? Какое-нибудь интер­ак­тив­ное поле, и таких полей нуж­но 15, и они долж­ны общать­ся меж­ду собой? Тогда опи­сы­вать каж­дое из них с нуля и как в пер­вый раз — очень гро­мозд­ко и затрат­но. А если потом нуж­но что-то изме­нить, то про­ще всё пере­пи­сать с нуля.

Вот тут и нужен React. Мы отдель­но опи­сы­ва­ем пове­де­ние каж­до­го эле­мен­та, отдель­но рас­став­ля­ем их и связываем.

Как устроена интерактивная часть статьи

Основ­ная часть ста­тьи — это про­сто HTML-код, кото­рый залит внутрь React-приложения. Ино­гда внут­ри это­го тек­ста встре­ча­ют­ся вот такие заклинания:

<Figure>
  <Grid 
    daysIncubating={0}
    daysSymptomatic={2}
    gridRows={9}
    gridCols={9}
    nodeSize={30}
    nug={1}
    randomSeed={100}
    personHours={4}
    showInteractions={false}
    speed={0.4}
    transmissionProbability={1}
    travelRadius={1}
  />
</Figure>

Перед нами — вызов ком­по­нен­тов Figure и Grid. За них отве­ча­ют фай­лы Grid.js и Figure.js — в них опи­са­ны пра­ви­ла, как имен­но бра­у­зе­ру сле­ду­ет исполь­зо­вать эти пара­мет­ры, что­бы нари­со­вать ани­ма­цию и под­пи­си к ней.

Пара­мет­ры каж­дой симу­ля­ции мы ука­зы­ва­ем пря­мо в тек­сте ста­тьи. Когда React рабо­та­ет, он заби­ра­ет эти пара­мет­ры из ста­тьи, пере­да­ёт в ком­по­нент, ком­по­нент обра­ба­ты­ва­ет эти пара­мет­ры и воз­вра­ща­ет в ста­тью гото­вый интер­ак­тив­ный виджет с симу­ля­ци­ей заражения.

Что это нам даёт:

  • Слож­ная логи­ка движ­ка симу­ля­ций про­пи­са­на где-то в отдель­ном месте, её не нуж­но дуб­ли­ро­вать. Если мы захо­тим поме­нять общий прин­цип рабо­ты симу­ля­то­ра, мы это сде­ла­ем в фай­лах Grid.js и Figure.js, не сло­мав саму статью.
  • Внут­ри ста­тьи мы про­пи­сы­ва­ем толь­ко суще­ствен­ные изме­не­ния в пове­де­нии симу­ля­ции: напри­мер, како­го раз­ме­ра будет симу­ля­ция, с какой ско­ро­стью будет про­те­кать, как люди будут заражаться.
  • Нам очень лег­ко добав­лять в ста­тью новые симу­ля­ции с любы­ми параметрами.
  • Код полу­ча­ет­ся эле­гант­ным и про­стым, хотя само при­ло­же­ние доволь­но сложное.

Где ещё используется React

Ста­тья Кеви­на Сим­ле­ра о пан­де­мии — лишь малая часть демон­стра­ции того, что уме­ет React.js. На самом деле эту биб­лио­те­ку исполь­зу­ют для про­ек­тов раз­но­го уров­ня, от част­ных, как у нас, до гло­баль­ных, как у этих ребят:

  • новост­ная лен­та в Facebook (соб­ствен­но, Facebook и раз­ра­бо­тал саму биб­лио­те­ку React.js);
  • почти весь види­мый поль­зо­ва­те­лю Instagram;
  • часть интер­фей­сов в WhatsApp;
  • Netflix;
  • сайт New York Times;
  • Yahoo! Mail;
  • Dropbox;
  • сот­ни дру­гих удоб­ных интер­фей­сов, кото­рые дела­ют про­грам­ми­сты по все­му миру.

С чего начать

Если вам понра­ви­лось, как мож­но рабо­тать с веб-страницами, нач­ни­те с этих материалов: