Interpolacja stringów

Przez cały kurs tworzymy stringi korzystając z trzech możliwych zapisów - cudzysłowów, apostrofów i backticków.


const text = "Stoi na stacji lokomotywa...";

const text = 'Stoi na stacji lokomotywa...';

const text = `Stoi na stacji lokomotywa...`;

W poniższym tekście przyjrzymy się dokładniej tym ostatnim czyli tak zwanym template strings czy też template literals.

Interpolacja

Interpolacja to zapis, za pomocą którego w łatwy sposób możemy do wnętrza tekstu wstawiać inne wartości:


const nr1 = 2;
const nr2 = 3;

const text = `Ala ma ${nr1} koty i ${nr2} psy.`;

Bezpośrednio do takiego tekstu możemy wstawiać kod JavaScript, w tym wywoływanie funkcji, zmienne itp:


const dayData = {
    temp : 23,
    weather : "pogodna"
}

function calculateWeather() {
    return "bardzo ładna :)"
}

const text = `
    Dzisiaj jest ${ (new Date()).getFullYear() }.
    Na dworze jest temperatura ${ dayData.temp }
    A pogoda jest ${ calculateWeather() }
`;

Funkcje tagujące

Funkcje tagujące to funkcje, które umożliwiają przekształcanie template strings. Są to zwykłe funkcje - jedyną różnicą jest sposób ich użycia. Jeżeli chcemy danej funkcji użyć jako funkcji tagującej, jej nazwę podajemy tuż przed początkiem template string:


function formatText() {
}

const txt = formatText`Przykładowy tekst bardzo fajny`;
console.log(txt);

Do funkcji takiej automatycznie są przekazywane w pierwszym parametrze poszczególne części template string (znajdujące się między zmiennymi), a do kolejnych parametrów zostaną przekazane kolejne zmienne użyte wewnątrz tekstu.


const formatString = (parts, var1, var2) => {
    console.log(parts); // ["Cena produktu A to ", " i jest o ", " tańsza od produktu B"]
    console.log(var1); //2000
    console.log(var2); //150
}

const price = 2000;
const diff = 150;
const text = formatString`Cena produktu A to ${price} i jest o ${diff} tańsza od produktu B`;

Im więcej takich zmiennych użytych w teście, tym dłuższa będzie tablica parts, ale też i więcej zmiennych będzie przekazanych do funkcji. Najczęściej nie będziemy dokładnie wiedzieli ile jest takich zmiennych, dlatego najlepszym rozwiązaniem jest zebrać je wszystkie pod jedną zmienną za pomocą rest operatora:


const format = (parts, ...vars) => {
    console.log(parts); //["Nazywam się ", " i mam ", " lat"] //długość 3
    console.log(vars); //["Piotr", 16] //długość zawsze o 1 mniejsza niż parts
}

const name = "Piotr";
const age = 16;

const text = format`Nazywam się ${name} i mam ${age} lat`;

const format = (parts, ...vars) => {
    console.log(parts); //["Cena tego produktu to ", ""] //długość 2
    console.log(vars); //[1000] //długość 1
}

const price = 1000;
const text = format`Cena tego produktu to ${price}`;

Główną zaletą funkcji tagujących jest to, że jeżeli zwrócą one jakąś wartość, zastąpi ona wartość template string:


const format = (parts, ...vars) => {
    return "Hej!";
}

const name = "Piotr";
const age = 16;

const text = format`Nazywam się ${name} i mam ${age} lat`;
console.log(text); //"Hej!"

Możemy to wykorzystać do modyfikacji naszych tekstów. Wystarczy zrobić pętlę po parts i vars łącząc odpowiednie części w jeden string.

W poniższym przykładzie każdą wartość z klamer dodatkowo modyfikuję za pomocą metody toFixed():


const formatString = (parts, ...vars) => {
    let str = "";
    parts.forEach((el, i) => {
        str += el;
        if (vars[i]) str += `${vars[i].toFixed(2)}zl`;
    });
    return str;
}

const price = 2000;
const diff = 150;

const text = formatString`Cena produktu A to ${price} i jest o ${diff} tańsza od produktu B`;

console.log(text); //"Cena produktu A to 2000.00zl i jest o 150.00zl tańsza od produktu B"

A tutaj z kolei każdą zmienną okryję elementem strong:


const markWithStrong = (parts, ...vars) => {
    let str = "";
    parts.forEach((el, i) => {
        str += el;
        if (vars[i]) str += `<strong>${vars[i]}</strong>`;
    });
    return str;
}

const name = "Marcin";
const dog = "Szamson";

const text = markWithStrong`Mam na imię ${name} a mój pies to ${dog}`;

console.log(text); //"Mam na imię <strong>Marcin</strong> a mój pies to <strong>Szamson</strong>"

Nie przekonałeś mnie. Dziwne te funkcje i pewnie nikt z tego nie korzysta.

A wręcz przeciwnie. Nie wiem, czy słyszałeś o czymś takim jak Styled Components? Jest to stylowanie komponentów za pomocą Javascript połączonego ze stylami - coś, co bardzo często używane jest przez developerów pracujących w Reakcie. Dzięki temu podejściu możemy CSS połączyć z dynamiką Javascriptu. Są tego oczywiście plusy, są i minusy, a w Internecie znajdziesz tyle samo osób którym ten pomysł się podoba, jak i nie podoba.

Poniżej screen z domowej strony tej biblioteki:


const Button = styled.a`
  /* This renders the buttons above... Edit me! */
  display: inline-block;
  border-radius: 3px;
  padding: 0.5rem 0;
  margin: 0.5rem 1rem;
  width: 11rem;
  background: transparent;
  color: white;
  border: 2px solid white;

  /* The GitHub button is a primary button
   * edit this to target it specifically! */
  ${props => props.primary && css`
    background: white;
    color: palevioletred;
  `}
`

Widzisz tą funkcje styled.a? Autorzy przygotowali dla nas naście funkcji tagujących (w tym a()) i umieścili je w we wspólnym tworze styled.

Tematu dogłębnie tutaj niestety nie podejmę, ponieważ nie jest to kurs Reacta. Stosowny artykuł możesz znaleźć np. tutaj

Wszelkie prawa zastrzeżone. Jeżeli chcesz używać jakiejś części tego kursu, skontaktuj się z autorem.
Aha - i ta strona korzysta z ciasteczek.