Back to Freecodecamp

Step 13

curriculum/challenges/english/blocks/workshop-toggle-text-app/67cd61c24bfc0a240132fd2f.md

latest5.9 KB
Original Source

--description--

It would be nice to dynamically show the words Show Message or Hide Message based on the isVisible state.

Earlier, you reviewed how to work with inline conditional rendering. You are going to apply similar logic to the button text.

Here is an example of using the ternary operator to conditionally show the words Hide and Show:

jsx
<button>{isMenuVisible ? "Hide" : "Show"} Menu</button>

For the last step of the workshop, use the ternary operator to conditionally display the words Hide or Show for the message button. Place the condition before the Message text so it displays Show Message or Hide Message.

And with that last change, your workshop is complete! Test your button to see it in action.

--hints--

When isVisible is false, the button text should say Show Message.

js
const btn = document.getElementById("toggle-button");
assert.equal(btn.textContent, "Show Message");

When isVisible is true, the button text should say Hide Message.

js
  const abuseState = __helpers.spyOn(React, "useState");
  const script = [...document.querySelectorAll("script")].find((s) => s.dataset.src ===  "index.jsx").innerText.replace("_React.useState", "abuseState");

  const exports = {};
  const a = eval(script);

  const s = await __helpers.prepTestComponent(exports.ToggleApp);

  const btn = s.querySelector('#toggle-button');
  assert.exists(btn);

  assert.equal(btn.textContent, "Show Message");
  
  await React.act(async () => {
    const ev = new MouseEvent("click", { bubbles: true, cancelable: true });
    btn.dispatchEvent(ev);
  });

  const alteredStates = abuseState.returns;
  const initialStates = alteredStates.splice(0, abuseState.returns.length / 2);

  const stateChanged = initialStates.some((s, i) => {
    try {
      assert.deepEqual(s[0], alteredStates[i][0]);
      return false; 
    } catch (e) {
      return true; 
    }
  });
 
  assert.equal(btn.textContent, "Hide Message");

  abuseState.restore();
  assert.isTrue(stateChanged);

--seed--

--seed-contents--

html
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <title>Toggle Visibility</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.3.1/umd/react.development.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.3.1/umd/react-dom.development.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/7.26.5/babel.min.js"></script>
  <script 
    data-plugins="transform-modules-umd"
    type="text/babel"
    src="index.jsx"
  ></script>
  <link rel="stylesheet" href="styles.css" />
</head>
<body>
  <div id="root"></div>
  <script
    data-plugins="transform-modules-umd"
    type="text/babel"
    data-presets="react"
    data-type="module"
  >
    import { ToggleApp } from "./index.jsx";
    ReactDOM.createRoot(document.getElementById("root")).render(<ToggleApp />);
  </script>
</body>
</html>
css
body {
  font-family: Arial, sans-serif;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  background-color: #f4f4f4;
}

#toggle-container {
  text-align: center;
  background: white;
  padding: 20px;
  border-radius: 10px;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

#toggle-button {
  padding: 10px 20px;
  border: none;
  background: #007BFF;
  color: white;
  border-radius: 5px;
  cursor: pointer;
  transition: background 0.3s ease;
}

#toggle-button:hover {
  background: #0056b3;
}

#message {
  margin-top: 20px;
  font-size: 1.125rem;
  color: #333;
}
jsx
const { useState } = React;

export const ToggleApp = () => {
  const [isVisible, setIsVisible] = useState(false);

  const handleToggleVisibility = () => {
    setIsVisible(!isVisible);
  }

  return (
    <div id="toggle-container">
    --fcc-editable-region--
      <button onClick={handleToggleVisibility} id="toggle-button">Message</button>
    --fcc-editable-region--
      {isVisible && <p id="message">I love freeCodeCamp!</p>}
    </div>
  );
};

--solutions--

html
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <title>Toggle Visibility</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.3.1/umd/react.development.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.3.1/umd/react-dom.development.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/7.26.5/babel.min.js"></script>
  <script 
    data-plugins="transform-modules-umd"
    type="text/babel"
    src="index.jsx"
  ></script>
  <link rel="stylesheet" href="styles.css" />
</head>
<body>
  <div id="root"></div>
  <script
    data-plugins="transform-modules-umd"
    type="text/babel"
    data-presets="react"
    data-type="module"
  >
    import { ToggleApp } from "./index.jsx";
    ReactDOM.createRoot(document.getElementById("root")).render(<ToggleApp />);
  </script>
</body>
</html>
css
body {
  font-family: Arial, sans-serif;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  background-color: #f4f4f4;
}

#toggle-container {
  text-align: center;
  background: white;
  padding: 20px;
  border-radius: 10px;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

#toggle-button {
  padding: 10px 20px;
  border: none;
  background: #007BFF;
  color: white;
  border-radius: 5px;
  cursor: pointer;
  transition: background 0.3s ease;
}

#toggle-button:hover {
  background: #0056b3;
}

#message {
  margin-top: 20px;
  font-size: 1.125rem;
  color: #333;
}
jsx
const { useState } = React;

export const ToggleApp = () => {
  const [isVisible, setIsVisible] = useState(false);

  const handleToggleVisibility = () => {
    setIsVisible(!isVisible);
  }

  return (
    <div id="toggle-container">
      <button onClick={handleToggleVisibility} id="toggle-button">
        {isVisible ? "Hide" : "Show"} Message
      </button>
      {isVisible && <p id="message">I love freeCodeCamp!</p>}
    </div>
  );
};