Вот пример объектов, с которыми я работал:

{
"index": 2,
"name": "Acolyte",
"size": "Medium",
"type": "humanoid",
"subtype": "any race",
"alignment": "any alignment",
"armor_class": 10,
"hit_points": 9,
"hit_dice": "2d8",
"speed": "30 ft.",
"strength": 10,
"dexterity": 10,
"constitution": 10,
"intelligence": 10,
"wisdom": 14,
"charisma": 11,
"medicine": 4,
"religion": 2,
"damage_vulnerabilities": "",
"damage_resistances": "",
"damage_immunities": "",
"condition_immunities": "",
"senses": "Passive Perception 12",
"languages": "any one language (usually Common)",
"challenge_rating": 0.25,
"special_abilities": [{
  "name": "Spellcasting",
  "desc": "The acolyte is a 1st-level spellcaster. Its spellcasting ability is Wisdom (spell save DC 12, +4 to hit with spell attacks). The acolyte has following cleric spells prepared:\n\n• Cantrips (at will): light, sacred flame, thaumaturgy\n• 1st level (3 slots): bless, cure wounds, sanctuary",
  "attack_bonus": 0
}],
"actions": [{
  "name": "Club"
  "desc": "Melee Weapon Attack: +2 to hit, reach 5 ft., one target. Hit: 2 (1d4) bludgeoning damage.",
  "attack_bonus": 2,
  "damage_dice": "1d4"
}],
"url": "http://www.dnd5eapi.co/api/monsters/2"
}

За свою ограниченную карьеру программиста у меня был некоторый опыт интерпретации и отображения данных JSON в javascript. Последние две недели я работал над проектом, созданным с помощью React, и обнаружил, что правила немного отличаются от тех, к которым я привык. React использует JSX, который выглядит и пахнет javascript, но это не то же самое.

Проект: Handy D&D (он же Handy Dandy). Цель состоит в том, чтобы предоставить мастерам подземелий простое вспомогательное приложение для проведения кампаний. Нам посчастливилось найти D&D 5e API, который был заполнен данными D&D (также известными как D&D). Я имею в виду, действительно круто: в 5-м издании D&D 325 монстров, в результате получается более 16 тысяч строк кода! Первой задачей, которую я предпринял, было разобрать JSON монстров, чтобы наши DM могли найти необходимую информацию о монстрах.

Один из первых уроков, который я усвоил, заключался в том, что если у одного из объектов-монстров (монстров?) Не было ключа, как у других монстров, попытка отобразить его привела бы к классической «Ошибка компиляции». Чтобы исправить это, я решил использовать операторы «если» для условного рендеринга контента. Однако вы не можете просто вставить вложенные операторы «если» в файл JSX, поэтому моя техника заключалась в том, чтобы вложить операторы «если» в функции, а затем вызвать эти функции для рендеринга контента.

Например:

function sense() {
if (monstersJSON.senses) {
return (
<div>
<p><strong>Senses:</strong> <em>{monstersJSON.senses}</em></p>
</div>
  )
 }
}

называется внутри фигурных скобок:

function MonsterDisplay(props) {
const monsterJSON = props.monster
if (monstersJSON) {
return (
<div>
{ sense() }
</div>
);
}
}

D&D имеет несколько значений, которые являются полуматематическими. Один из примеров - очки опыта для рейтингового испытания. У монстров есть рейтинг опыта, который переводится в очки опыта. Поскольку они не следуют простой математической зависимости, я не мог использовать математическую функцию, чтобы определить, сколько опыта нужно отобразить для данного рейтинга сложности.

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

const challengeRatingXP = {
.125: 25,
.25: 50,
.5: 100,
1: 200,
2: 450,
3: 700,
4: 1100,
5: 1800,
… }

Поступая так, я мог использовать рейтинг сложности от объекта-монстра в качестве ключа для получения очков опыта в качестве значения. Вот как я настроил JSX для отображения искомых значений:

<p>Challenge: 
{monsterJSON.challenge_rating} 
( {challengeRatingXP[monsterJSON.challenge_rating]} XP) 
</p>

Итак, для монстра с рейтингом сложности 3 приложение отобразит:

Испытание: 3 (700XP)

Используя аналогичную логику, я смог интерпретировать и отображать модификаторы силы, ловкости, телосложения, интеллекта, мудрости и харизмы.

const abilityScoreModifier = {
…
8: “-1”,
9: “-1”,
10: “0”,
11: “0”,
12: “+1”,
13: “+1”,
… }

Я сохранил значения в виде строк, чтобы отображать их обычным способом D&D: «INT 16 (+2)» или «CHA 5 (-3)». Изучая D&D, я обнаружил, что у каждого монстра есть бонус хитов, который можно добавить к их кубикам атаки. Этот бонус не указан явно в объекте JSON монстра, но рассчитывается путем умножения количества выпавших кубиков на множитель Конституции. Очаровательно, правда ?!

Количество выпавших кубиков сохранялось в виде строки в формате «8d10» (8 десятигранных игральных костей) или «10d6» (10 шестигранных игральных костей). Поэтому я решил, что разделю эту строку на символ «d», вернув только 1-е значение, что приведет к количеству пораженных кубиков в виде строки.

На данный момент у меня есть значение модификатора в виде строки и количество ударов в виде строки, и, конечно же, мне пришлось бы использовать parseFloat () или parseInt (), чтобы получить числовое значение, верно? неправильный! Когда я это сделал, React сразу напомнил мне, что это не функции. Однако, когда я подключил строки к вычислениям, все заработало. Я предполагаю, что у React есть некоторая встроенная «нечеткая» логика для интерпретации длинных чисел.

Кроме того, у монстров есть особые способности, действия и легендарные действия. У любого монстра может быть комбинация всех трех или ни одного. Все эти характеристики представлены в виде массивов. Мой товарищ по команде Джейкоб предусмотрительно использовал функцию карты для отображения этих значений. Я использовал свои уроки из предыдущих характеристик, чтобы объединить три различные функции условной карты до одной, в которой я передал заголовок и местоположение массива, который я искал. Вот функция, которую я использовал:

function mapDisplay(titleString, jsonLocation) {
if(jsonLocation) {
return(
<div>
<h2><strong>{titleString}</strong></h2>
{jsonLocation.map(location => (
<div>
<hr></hr>
<p><strong>{location.name + “: “}</strong></p>
<p><em>{location.desc}</em></p>
</div>
))}
</div>
)
}
}

А вот как я назвал функцию:

{mapDisplay(“Special Abilities” monstersJSON.special_abilities)}{mapDisplay(“Actions”, monstersJSON.actions)}
{mapDisplay(“Legendary Actions”, mmonstersJSON.legendary_actions)}

Это был интересный способ узнать как реагировать, так и больше о D&D. Надеюсь, вам понравилось это читать!