0

I have the following code just to simulate my problem. I would like to conditionally render a component on button click. Here is the code that I have, how do I render the component conditionally using a function and a switch case. Remember I am using only functional components and not class components.

import React from "react";
import ReactDOM from "react-dom";

import One from "./One";
import Two from "./Two";
import Three from "./Three";
import None from "./None";

import "./styles.css";
const handleRender = (e, props) => {
  let exp = Math.floor(Math.random() * props);
  console.log(exp);
  return exp;
};
function Test(exp) {
  switch (exp) {
    case 1:
      return <One />;
    case 2:
      return <Two />;
    case 3:
      return <Three />;
    default:
      return <None />;
  }
}
function App() {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <button onClick={(e, p) => handleRender("a", "5")}>
        Render One Two or Three
      </button>
      <Test />
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

https://codesandbox.io/s/clever-merkle-ln8wf

0

3 Answers 3

1

You can achieve what you want with the App function below

function App() {
  const [state, setState] = React.useState(null)
  const testNode = Test(state)

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <button onClick={(e, p) => setState(handleRender("a", "5"))}>
        Render One Two or Three
      </button>
      {testNode}
    </div>
  );
}

But, I wouldn't recommend this approach for such task

Sign up to request clarification or add additional context in comments.

2 Comments

Why won't you recommend this approach though?
You build your test function like a component. But in fact, it's just a mapper. you can define your map object like this: const map = { case1: CompA, case2: CompB }. Then in render method, you can choose your component constructor like: const ConditionalComp = map[state]. And in return element you can just use <ConditionalComp />. In future, if you need to pass props to these components, you wouldn't need to pass them around.
1

You need to add a state:

const handleRender = (e, props) => {
  let exp = Math.floor(Math.random() * props);
  console.log(exp);
  return exp;
};
function Test(exp) {
  switch (exp) {
    case 1:
      return <One />;
    case 2:
      return <Two />;
    case 3:
      return <Three />;
    default:
      return <None />;
  }
}
function App() {
  const [exp, setExp] = useState(0);
  return (
    <div className="App">
      <button onClick={() => setExp(handleRender('a', '5'))}>
        Render One Two or Three
      </button>
      {Test(exp)}
    </div>
  );
}

Edit stupefied-architecture-3q90r

1 Comment

This solution makes sense to me!
1

You could use hooks to keep track of the click, then conditionally render.

For example:

import React, { useState } from "react";

// Your other imports.

function Test(exp) {
  switch (exp) {
    case 1:
      return <One />;
    case 2:
      return <Two />;
    case 3:
      return <Three />;
    default:
      return <None />;
  }
}

// this would be if you want to generate a random component
function randomIntFromInterval(min, max) {
  return Math.floor(Math.random()*(max-min+1)+min);
}

function App() {
  const [renderedComponent, setRenderedComponent] = useState(0);
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      // If you want a button for a particular component, you can
      // put in that number 1,2,3 instead of the call to randomIntFromInterval
      <button onClick={() => setRenderedComponent(randomIntFromInterval(1, 3))}>
        Render One Two or Three
      </button>
      {renderedComponent !== 0 && <Test />}
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

This won't stop the button from being clicked again however, and possibly displaying another component. You'll have to introduce logic to handle that.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.