Help with understanding codecademy store, createCurrencyButton(currency) function

*Codecademy Store Lesson

The partial code is from the CurrencyFilter.js feature (the full code for this component is at bottom of this post).

I understand the following code which displays the three currency buttons on the web page with the exception of this line

        className={`currency-button ${ currencyFilter === currency && 'selected'  }`}

Code and relevant CSS:

  return (
    <div id="currency-filters-container">
      <h3>Choose a currency</h3>
      {currenciesData.map(createCurrencyButton)} {/*for each currency in ['USD', 'EUR', 'CAD'] createCurrrencyButton will be called  */}
    </div>                                        
  );

  /*from currenciesData from data.js, the function below will be called 3 times hence three buttons will be created */
  function createCurrencyButton(currency) {
    return (
      <button
        **className={`currency-button ${ currencyFilter === currency && 'selected'  }`}**
        key={currency} 
        onClick={() => onClickHandler(currency)}
      >
        {currency} {/* label for buttonL USD, EUR, CAN */}
      </button>
    );
  }

CSS:

.currency-button {
  background: white;
  border: 1px solid var(--black);
  padding: 8px;
  font-weight: 600;
  cursor: pointer;
}

.currency-button:first-of-type {
  border-top-left-radius: var(--border-radius);
  border-bottom-left-radius: var(--border-radius);
}

.currency-button:last-of-type {
  border-top-right-radius: var(--border-radius);
  border-bottom-right-radius: var(--border-radius);
}

.currency-button.selected {
  background: var(--black);
  color: white;
}

Complete CurrencyFilter.js

import React from 'react';

import { currenciesData } from '../../data.js';
import { setCurrency } from './currencyFilterSlice.js';

//The currencyFilter component rendered at top of page
//currencyFilter and dispatch passed in from App.js
//this will render 'Choose a currency and three buttons "USD, EUR, CAD"
export const CurrencyFilter = ({ currencyFilter, dispatch }) => {
  console.log(currencyFilter)
  const onClickHandler = (currency) => {
    dispatch(setCurrency(currency)); //imported from the currency slice (see above)
  };

  return (
    <div id="currency-filters-container">
      <h3>Choose a currency</h3>
      {currenciesData.map(createCurrencyButton)} {/*for each currency in ['USD', 'EUR', 'CAD'] createCurrrencyButton will be called  */}
    </div>                                        
  );

  /*from currenciesData from data.js, the function below will be called 3 times hence three buttons will be created */
  function createCurrencyButton(currency) {
    return (
      <button
        className={`currency-button ${
          currencyFilter === currency && 'selected' 
        }`}
        key={currency} 
        onClick={() => onClickHandler(currency)}
      >
        {currency} {/* label for buttonL USD, EUR, CAN */}
      </button>
    );
  }
};

Have a look at the documentation for these:

Logical AND (&&) evaluates operands from left to right, returning immediately with the value of the first falsy operand it encounters; if all values are truthy, the value of the last operand is returned.

With the above in mind, consider the example:

console.log(1 == 1 && "selected");
// Output: 'selected'
// The first operand evaluates to true, so the second operand is evaluated
// and the string `selected` is returned.

console.log(1 == 2 && "selected");
// Output: false
// The first operand evaluates to false, so the second operand is not evaluated.

console.log("selected" && 1 == 1);
// Output: true
// The first operand is truthy, so the second operand is evaluated
// and the boolean true is returned.

console.log("selected" && 1 == 2);
// Output: false
// The first operand is truthy, so the second operand is evaluated
// and the boolean false is returned.

console.log(1 == 1 || "selected");
// Output: true
// The first operand evaluates to true, so the second operand is not evaluated.

console.log(1 == 2 || "selected");
// Output: 'selected'
// The first operand evaluates to false, so the second operand is evaluated
// and the string 'selected' is returned.

console.log("selected" || 1 == 1);
// Output: 'selected'
// The first operand is truthy, so the second operand is not evaluated.

console.log("selected" || 1 == 2);
// Output: 'selected'
// The first operand is truthy, so the second operand is not evaluated.

You wrote:

className={`currency-button ${ currencyFilter === currency && 'selected'  }`}

The map method will iterate over the currenciesData i.e. over the array ['USD', 'EUR', 'CAD'], and in each iteration one of the array elements will be passed as the argument to the createCurrencyButton function.

If the currency matches the currencyFilter, then the button will be assigned two classes: currency-button and selected.
If the currency doesn’t match the currencyFilter, then the button will be assigned two classes: currency-button and false.

Suppose the currencyFilter was 'EUR', then you will end up with three buttons:

<button class="currency-button false" key="USD">USD</button>
<button class="currency-button selected" key="EUR">EUR</button>
<button class="currency-button false" key="CAD">CAD</button>

In your CSS file, you have a selector targeting all buttons,

.currency-button {
...
}

The selector

.currency-button.selected {
...
}

allows you to target the button which has both of these classes.

If you wanted to target the two other buttons, you could use a selector such as:

.currency-button.false {
...
}

where false is the name of the second class assigned to the buttons.

Again thanks for the reply. Great answer.

1 Like