
Myślę, że przy piątku lepiej będzie napisać coś trochę lżejszego. Pozostajemy jednak w tematyce ReactJS! Dziś przedstawię Ci prosty sposób na dynamiczna wartość atrybutu className. Osiągniemy to dzięki jednej sprytnej bibliotece… Używam jej w praktycznie każdym komponencie prezentacyjnym - moim zdaniem jest na prawdę bardzo przydatna. Zresztą za chwilę sam się przekonasz.

ReactJS - dynamiczna wartość atrybutu className
Myślę, że przy piątku lepiej będzie napisać coś trochę lżejszego. Pozostajemy jednak w tematyce ReactJS! Dziś przedstawię Ci prosty sposób na dynamiczna wartość atrybutu className. Osiągniemy to dzięki jednej sprytnej bibliotece… Używam jej w praktycznie każdym komponencie prezentacyjnym - moim zdaniem jest na prawdę bardzo przydatna. Zresztą za chwilę sam się przekonasz.
Dynamiczna wartość atrybutu className
Zanim przedstawię Ci wspomnianą bibliotekę, dla porządku wspomnę jak dynamiczna wartość atrybutu className osiągalna jest standardowo, bez użycia zewnętrznych bibliotek. Spójrz na poniższy przykład komponentu ReactJS:
import React from 'react';
const exampleComponent = (props) => {
const isActive = props.isActive ? 'active' : '';
const isEnabled = props.isEnabled ? 'enabled' : '';
return (
<div className={`container ${isActive} ${isEnabled}`}>
...
</div>
);
};
export defaut exampleComponent;
Jak widzisz, komponent exampleComponent
zwraca element div
, któremu nadaję trzy klasy CSS. Pierwsza z nich to ustawiona na sztywno klasa container
. Dwie następne ustawiane są dynamicznie. Dynamiczne dlatego, że w zależności od wartości parametru dostępnego w “propsach” mają one inną wartość.
Dodatkowo zwróć też uwagę w jaki sposób definiuję wartość atrybutu className
. Jest to zapis dostępny w ES6, pozwalający na parametryzowanie ciągów znaków. Jak widzisz, aby przekazać do “stringa” parametr, używamy zapisu ${zmienna}
.
Tak mniej więcej wygląda standardowy sposób na definiowanie dynamicznych wartości parametru className
. Nie wygląda to źle choć można się domyślić, że kiedy parametrów będzie dużo, definicja atrybutu className
zrobi się dość rozbudowana…
Na szczęście ktoś już o tym pomyślał i stworzył dedykowaną bibliotekę!
Zróbmy to lepiej - biblioteka classnames
No dobrze, czas przedstawić głównego bohatera dzisiejszego wpisu czyli bibliotekę classnames
- tutaj link do projektu na GitHub. Generalnie służy ona po prostu do warunkowego łączenia ciągów znaków w jeden ciąg wynikowy.
Zanim przejdziemy dalej, sprawdźmy jak zainstalować, a później używać tej biblioteki.
Instalacja i użycie
Jak wszystko w świecie ReactJS, bibliotekę classnames
instaluje się za pomocą NPM:
npm install classnames
Teraz możesz już zwyczajnie zaimportować classnames
w swoim module.
Czas teraz przejść do przykładowego użycia tej biblioteki. Jest to bardzo proste. Spójrz na poniższy przykład (zaczerpnięty z pliku README biblioteki):
import classNames from 'classnames';
classNames('foo', 'bar'); // => 'foo bar'
classNames('foo', { bar: true }); // => 'foo bar'
classNames({ 'foo-bar': true }); // => 'foo-bar'
classNames({ 'foo-bar': false }); // => ''
classNames({ foo: true }, { bar: true }); // => 'foo bar'
classNames({ foo: true, bar: true }); // => 'foo bar'
// lots of arguments of various types
classNames('foo', { bar: true, duck: false }, 'baz', { quux: true });
// => 'foo bar baz quux'
// other falsy values are just ignored
classNames(null, false, 'bar', undefined, 0, 1, { baz: null }, '');
// => 'bar 1'<br>
Jak widzisz funkcja classNames
, którą zaimportowaliśmy w pierwszej linii przykładu przyjmuje ciągi znaków i/lub obiekty jako parametry. Jeśli przekażesz same “stringi”, metoda classNames
zwyczajnie połączy je używając znaku spacji jako separatora.
Drugi i bardziej interesujący sposób to przekazanie obiektu jako parametr. Właściwości tego obiektu powinny mieć przypisane wartości typu bool
. Jeśli przypiszesz do właściwości wartość true
to nazwa tej właściwości znajdzie się w wynikowym ciągu znaków. Jeżeli natomiast przypiszesz jej wartość false
, to zostanie ona pominięta. Tak, to jest tak proste!
Funkcja classNames
jako dynamiczna wartość atrybutu className
No dobra. Myślę, że wiemy już wszystko co potrzeba aby wykorzystać bibliotekę classnames
w naszym przykładowym komponencie. Spójrzmy na zmodyfikowany komponent exampleComponent
, w którym wykorzystałem funkcję classNames
:
import React from 'react';
import classNames from 'classnames';
const exampleComponent = (props) => {
const classValue = classNames({
'container': true,
'active': props.isActive,
'enabled': props.isEnabled
});
return (
<div className={classValue}>
...
</div>
);
};
export defaut exampleComponent;
W powyższym przykładzie użyłem funkcji classNames
do przygotowania ciągu znaków, który przekazuję do atrybutu className
elementu div
.
Zwróć uwagę na obiekt, który przekazuję do funkcji classNames
. Jego właściwość container
jest ustawiona na true
więc po prostu zostanie ona wrzucona do wynikowego “stringa”. Pozostałe właściwości zależą od właściwości obiektu props
. W zależności od tego jakie są te wartości, nazwy właściwości obiektów trafią do wynikowego ciągu lub nie. W efekcie do zmiennej classValue
przypisany zostanie ciąg znaków zawierający odpowiednie nazwy właściwości oddzielone spacją.
Jeśli spojrzysz teraz na element div
zauważysz, że tym razem do jego atrybutu className
przekazuję po prostu zmienną, do której przypisałem wynik działania funkcji classNames
. Element ten, ma więc teraz nadane odpowiednie klasy.
Wydaje mi się, że powyższy zapis jest znacznie bardziej czytelny. Osobiście zawsze stosuję bibliotekę classnames
przy tworzeniu dynamicznych wartości atrybutu className.
Podsumowanie
To tyle na dziś. Mam nadzieję, że przedstawiona przeze mnie biblioteka okaże się dla Ciebie przydatna. Ciekaw jestem Twojej opinii o przedstawionym dziś podejściu…
Jako uzupełnienie powyższego artykuły stworzyłem również video tutorial, dostępny na moim kanale w serwisie youtube. Zachęcam do subskrypcji tego kanału, ponieważ na pewno będą się tam pojawiać kolejne video tutoriale! Poniżej przedstawiam wspomniany film: