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
Trening czyni mistrza
Jeżeli chcesz sobie potrenować zdobytą wiedzę, zadania znajdują się w repozytorium pod adresem: https://github.com/kartofelek007/zadania