React i JSX rewolucją dla programowania GUI ?

Chciałbym w tym krótkim poście wyrazić moją opinię na temat React’a oraz JSX oraz pokazać gdzie obecnie możemy użyć podejścia React’owego. Miłego czytania :).

W ostatnim czasie React oraz jego ecosystem staje się coraz bardziej stabilny. Śmiem powiedzieć, że React jest sposobem myślenia, nie tylko biblioteką w JSie do tworzenia aplikacji działających w przeglądarkach.

Świat webowy

Pierwszym dużym produktem Facebooka był wyżej wymieniony React wraz z JSXem. Pozwalał przekształcić kod tego typu:

$("#snowHealth").text(jonSnow.healthPoints);
    $("#drogoHealth").text(khalDrogo.healthPoints);
    $("#cleganeHealth").text(gregorClegane.healthPoints);
    $("#lanisterHealth").text(jamieLanister.healthPoints);

    //Select protagonist in this section
    $("#characters").on("click", "#snow", function () {
        $("#snow").addClass("myCharacter");
        var enemy1 = $("#khal");
        var enemy2 = $("#gregor");
        var enemy3 = $("#lanister");
        $("#enemySelect").append(enemy1);
        $("#enemySelect").append(enemy2);
        $("#enemySelect").append(enemy3);
        enemy1.addClass("enemyCard");
        enemy2.addClass("enemyCard");
        enemy3.addClass("enemyCard");
    });

w komponent który wygląda przyjaźniej:

class HelloMessage extends React.Component {
  render() {
    return (
      <div>
        Hello {this.props.name}
      </div>
    );
  }
}

ReactDOM.render(
  <HelloMessage name="Taylor" />,
  mountNode
);

Warto zaznaczyć, że React doczekał się super lekkiej alternatywy, Preact’a.

Świat mobilny

Kolejnym produktem który wypuścił Facebook był React Native. Zamiast dobrze znanych w świecie webowym elementów jak divspan czy p dostaliśmy TextScrollView czy Switch. Koncepcja architektoniczna jest taka sama jak w Reactcie webowym. Aplikacja jest zbudowana z komponentów, komunikacja między nimi następuje w jednym kierunku poprzez propsy, używamy JSX do opisu elementów UIowych. Dotychczasowe podejście w świecie mobilnym było różne w zależności od platformy, aczkolwiek mogę się pokusić o jeden wspólny pierwiastek dla Androida oraz iOSa, elementy UIowe są opisane w XMLu. Później za pomocą eventów programujemy działanie aplikacji. Architektura z grubsza przypomina MVC.

Przykładem może być tutaj tworzenie aplikacji pod iOS. Po wyklikaniu startowego projektu powinniśmy zobaczyć designer. Tutaj screenshot jak to wygląda 😉 :

Za pomocą toolbara możemy drag&drop’em przerzucać elementy na widok. Na tej podstawie generowany jest XMLem z opisem widoku. Przypomina to dość mocno HTML ;). Tutaj fragment wygenerowanego XMLa:

<scenes>
        <!--View Controller-->
        <scene sceneID="tne-QT-ifu">
            <objects>
                <viewController id="BYZ-38-t0r" customClass="ViewController" customModule="ToDoApp" customModuleProvider="target" sceneMemberID="viewController">
                    <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                        <subviews>
                            <button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="aK9-Fk-gBW">
                                <rect key="frame" x="155" y="184" width="64" height="30"/>
                                <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
                                <state key="normal" title="Click me!"/>
                            </button>
                        </subviews>
                        <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                        <viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
                    </view>
                </viewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
            </objects>
        </scene>
    </scenes>

Podobnie sprawa wygląda na Androidzie.

W React Native kod wygląda przyjemniej, z pomocą komponentów i JSX’a sami decydujemy jaki ma być podział kodu opisującego UI.  Przykład komponentu w React Native:

import React, { Component } from 'react';
import { Text, View } from 'react-native';

class WhyReactNativeIsSoGreat extends Component {
  render() {
    return (
      <View>
        <Text>
          If you like React on the web, you'll like React Native.
        </Text>
        <Text>
          You just use native components like 'View' and 'Text',
          instead of web components like 'div' and 'span'.
        </Text>
      </View>
    );
  }
}

Świat konsolowy

Może kilka osób z was będzie zaskoczonych, ale istnieje biblioteka która umożliwia pisanie aplikacji konsolowych w stylu Reactowym ;). Jej nazwa to Ink. Przypomniało mi się teraz wiele aplikacji które pisałem jeszcze w C++, za każdym razem trzeba było stworzyć sporo kodu który służył tylko do czyszczenia ekranu i innych UIowych rzeczy, z Ink’iem sprawa wygląda o wiele przyjaźniej, JSX oraz komponenty React’owe robią robotę. Dostępne komponenty to między innymi spinnerinput czy image( tak, tak, jest możliwe wczytanie obrazka w aplikacji konsolowej 😉 ).

Oto przykład komponentu w którym wyświetlamy użytkownikowi input:

const {h, render, Component} = require('ink');
const SelectInput = require('ink-select-input');

const Demo = () => {
	const handleSelect = item => {
		// `item` = { label: 'First', value: 'first' }
	};

	const items = [{
		label: 'First',
		value: 'first'
	}, {
		label: 'Second',
		value: 'second'
	}, {
		label: 'Third',
		value: 'third'
	}];

	return <SelectInput items={items} onSelect={handleSelect}/>
};

render(<Demo/>);

Po uruchumieniu powinniśmy zobaczyć coś takiego:

Przyznajcie, że całkiem spoko ^^

Świat gier

W świecie gier także istnieje narzędzie które pozwala tworzyć komponenty React’owe. Jest to React Game Kit. Ze wszystkich projektów wygląda najmniej interesująco. Obecne środowiska jak Unity3D albo Unreal wydają się lepszymi alternatywami. Jednak warto wiedzieć, że coś takiego jak React Game Kit w ogóle istnieje 😉

Świat desktopowy

Jest to dość świeży temat. Do 2017 roku jedyną opcją stworzenia aplikacji desktopowej w JSie było użycie Electrona. Electron nie jest do końca natywnym rozwiązaniem, pod spodem odpalana jest instancja Chromium. W 2018 roku pojawiła się interesująca alternatywa dla Electrona, jest to projekt Proton Native. Założenie jest podobne do React Native’a. Z pomocą tego samego podejścia co w webowym React’cie mamy możliwość tworzyć natywne aplikacje na systemy desktopowe. W tym aspekcie mamy wiele możliwości. Możemy tworzyć aplikacje w Qt które działają na wszystkich systemach, możemy także użyć WPF w C#, tudzież starych WinForms’ów. Na systemach z jabłkiem z kolei możemy użyć framework’a cocoa. Mam nadzieję, że Proton będzie się rozwijać i w przyszłości powalczy o rynek desktopowy. Tutaj przykład kodu oraz aplikacji zrobionej z pomocą Proton Native (przykład z strony):

Podsumowanie

W ostatnim czasie po dużym sukcesie React’a w świecie webowym, coraz więcej narzędzi chce czerpać z podejścia React’a. Wydaje mi się, że będzie to rzecz dzięki której React będzie postrzegany jako coś więcej niż tylko libka do robienia frontendu. Jakie są wasze opinie ? Może znacie jakieś inne frameworki inspirowane React’em ?