Interpolacja stringów

Ostatnia aktualizacja: 16 lutego 2020

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

Trening czyni mistrza

Jeżeli chcesz sobie potrenować zdobytą wiedzę z tego działu, to zadania znajdują się w repozytorium pod adresem: https://github.com/kartofelek007/zadania-podstawy

W repozytorium jest branch "solutions". Tam znajdziesz przykładowe rozwiązania.

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.

Menu