0

I'm doing an test here in my react application and I get a boolean as a parameter from an external object, by checking that boolean, I need to return a code snippet in my view.

This is my code that checks whether the value is true or false:

appInstance.get(myTest)
  .then((value) => {
    if (value.something === true) {
      setContent
    } else {
      setAnotherContent
    }
  });

I must return in the same return different blocks according to my conditional above

  return (
      // if value.something === true, show this content
      <h2>Title one</h2>
      <p>Some text</p>
      
      // else
      <h2>Title two</h2>
      <p>Some text two</p>

      // a lot of code below that doesn't change
      {...}
     )

What is the best way to do this using react?

CodeG
  • 417
  • 2
  • 6
  • 15
  • 1
    Don't return jsx from async callbacks. Update a `state` property in `.then()` callback. Use the same property in `render` to conditionally display the data. Use [`useEffect`](https://stackoverflow.com/questions/53219113/where-can-i-make-api-call-with-hooks-in-react) if you are using hooks – adiga May 26 '21 at 15:53
  • create components for setContent and setAnotherContent and return them. Will be much neater. Also try using async/await or state changes for callbacks. – Visakh Vijayan May 26 '21 at 15:53

4 Answers4

0

first, you need to set value as state so that it will be re-rendered every time the value changes. Since it seems that u're using functional component, you can declare it as:

const [value, setValue] = useState(false)

Don't forget to import useState before using it,

then you call it inside your function (also as @adiga said, you need to put this inside useEffect depending when you want to call it):

appInstance.get(myTest)
  .then((value) => {
    setValue(value)
  });

after that, you do conditional rendering such as:

if(value) {
return (
      // if value === true, show this content
      <h2>Title one</h2>
      <p>Some text</p>
) } else {
return (
      <h2>Title two</h2>
      <p>Some text two</p>
)}

if you want to call it in one return, you can use ternary expression in javascript like this:

return (
      <>
      {value ? <h2>Title one</h2> : <h2>Title two</h2>}
      {value ? <p>Some text</p> : <p>Some text two</p>}

      // a lot of code below that doesn't change
      {...}
      </>
     )
0

You could make a renderContent method:

const MyComponent = () => {
  // ...

  const renderContent = () => {
    if (somethingIsTrue) {
      return (
        <h2>Title one</h2>
        <p>Some text</p>
      )
    } else {
      return (
        <h2>Title two</h2>
        <p>Some text two</p>
      )
    }
  }

  return (
    {renderContent()}
    // ...
    // remaining JSX here
  )
}

Nitsew
  • 3,612
  • 1
  • 15
  • 20
  • This did not work because I was unable to load the component inside return. I need put the const renderContent inside the appInstance? – CodeG May 26 '21 at 18:00
0

You can use useState to set the content you want to render, after your promise resolves inside of a useEffect.

const { useEffect, useState } = React;

const
  myTestApp = 'app',
  appInstance = {
    get(app) {
      return Promise.resolve({ something: true });
    }
  };

const SuccessContent = () => (
  <React.Fragment>
    <h2>Success</h2>
    <p>Request was successful!</p>
  </React.Fragment>
);

const FailureContent = () => {
  <React.Fragment>
    <h2>Failure</h2>
    <p>Request failed...</p>
  </React.Fragment>
};

const Example = (props) => {
  const [content, setContent] = useState(0);

  useEffect(() => {
     appInstance.get(myTestApp)
      .then((value) => {
        if (value.something === true) {
          setContent(<SuccessContent />);
        } else {
          setContent(<FailureContent />);
        }
      });
  }, []);

  return (
    <div>
      {content}
      <p>Rest of content...</p>
    </div>
  );
};

ReactDOM.render(<Example />,document.getElementById("react"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
0

Use ternary operator

      { value.something ? (
             <h2>Title one</h2>
             <p>Some text</p>
        ) : (
             <h2>Title two</h2>
             <p>Some text two</p>
             <p>Some text two</p>
        )}
timthedev07
  • 454
  • 1
  • 6
  • 17