Hesam Alavi
Hesam Alavi

Reputation: 159

How to get react app to render after event?

I have a simple app and don't want to use props, etc. as i am just learning react and want to keep things simple. The app has a button and when the button ("show details") is clicked a message shows up under the button, and the button changes to "hide details". When the hide details is clicked on the message disappears. The app works up to this point, but I need it to toggle back and forth, that is every time the button is clicked the message either shows up or hides, and the text on the button changes too.

const app = {
  title: 'Visibility Toggle',
  toggleOptions: ''
};

const hideDetails = () => {
  app.toggleOptions = [];
  render();
};
const showDetails = () => {
  app.toggleOptions = 'There is a message here';
  render();
};

const appRoot = document.getElementById('app');

const render = () => {
  const template = (
    <div>
      <h1>{app.title}</h1>
      <button onClick={!app.toggleOptions ? showDetails : hideDetails}>
        {!app.toggleOptions ? 'Show Details' : 'Hide Details'}
      </button>
      <p>{app.toggleOptions}</p>
    </div>
  );
  ReactDOM.render(template, appRoot);
};
render();
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Toggle App</title>
  </head>

  <body>
    <div id="app"></div>
    <script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
    <script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>
    <script src="/scripts/app.js"></script>
  </body>
</html>

Upvotes: 0

Views: 48

Answers (2)

Hesam Alavi
Hesam Alavi

Reputation: 159

I figured it out, line 7,

app.toggleOptions = [];

should be

app.toggleOptions = "";

Upvotes: 0

khan
khan

Reputation: 1464

When you call hideDetails(), you set app.toggleOptions to an empty array. An empty array is considered a truthy value, so your ternary operator inside of template will resolve to hideDetails(). You can check the whether a value is truthy or falsy by using the double NOT operator, !!.

const app = {
  title: 'Visibility Toggle',
  toggleOptions: ''
};

const hideDetails = () => {
  app.toggleOptions = ''; // Change [] to a falsy value
  render();
};
const showDetails = () => {
  app.toggleOptions = 'There is a message here';
  render();
};

const appRoot = document.getElementById('app');

const render = () => {
  const template = (
    <div>
      <h1>{app.title}</h1>
      <button onClick={!app.toggleOptions ? showDetails : hideDetails}>
        {!app.toggleOptions ? 'Show Details' : 'Hide Details'}
      </button>
      <p>{app.toggleOptions}</p>
    </div>
  );
  ReactDOM.render(template, appRoot);
};
render();

console.log('This is falsy:', !!'')
console.log('This is truthy:', !![])
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Toggle App</title>
  </head>

  <body>
    <div id="app"></div>
    <script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
    <script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>
    <script src="/scripts/app.js"></script>
  </body>
</html>

Upvotes: 1

Related Questions