2

I'm trying to return a function component after the condition is checked within a class component. Here is my code:

 class Page extends React.Component {
  constructor(props) {
    super(props);
    this.state = props.warn;
  }

   function WarningBanner() {
    if (this.state == false) {
      return null;
    }

    return (
      <div className="warning">
        Warning!
      </div>
    );
  } 
  render() {
    return (
      <div>
        <WarningBanner />
      </div>
    );
  }
}

ReactDOM.render(
  <Page warn={true}/>,
  document.getElementById('root')
);

Is a function component inside a class component considered a valid component ? Or is there a another way to define a function component inside a class component?

What is the difference between a function component inside class component or a function component outside a class component ?

I have also tried doing this:

<WarningBanner warn = {this.state}/>

And

function WarningBanner(warning) {
    if (warning.warn == false) {
      return null;
    }
    return (<div className="warning">Warning!</div>);
  }
1

3 Answers 3

2

Yes, function compoment inside the class component is valid and it is possible to share state of main component too and their is no difference in function component and function component inside class component as individial component.
Problem here is entirely related to javascript rather than react. Here is the right code:

class Page extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: props.warn};
    this.warning = this.WarningBanner.bind(this);
  }
  WarningBanner() {
    if (this.state.value == false) { 
      return null;
    }
    return (<div className="warning">Warning!</div>);
  }

  render() {
    return (<div>{this.warning()}</div>);
  }
}

ReactDOM.render( <Page warn={true}/>, document.getElementById('root'));

Problem 1: function keyword can not be defined inside javascript class since class itself supposed to act like a function.

Problem 2: New functions in javascript class needs to be 'bind' and access by 'this.warning' variable.

I hope it will be useful for someone. Thanks.

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

Comments

1

You could do something like...

    class Page extends React.Component {
  constructor(props) {
    super(props);
    this.state = props.warn;
  }

  render() {
    return (
      <div>
        {this.props.warn && <div className="warning">Warning!</div>}
      </div>
    );
  }
}

ReactDOM.render(
  <Page warn={true}/>,
  document.getElementById('root')
);

Where {this.props.warn && <div className="warning">Warning!</div>} will evaluate if the condition is true and, if so, render the component.

If you wanted to make a more complex functional component, I would suggest creating it outside of your stateful component like this...

const Warning = () => {
  return (<div className="warning">Warning!</div>);
}

class Page extends React.Component {
  constructor(props) {
    super(props);
    this.state = props.warn;
  }

  render() {
    return (
      <div>
        {this.props.warn && <Warning />}
      </div>
    );
  }
}

ReactDOM.render(
  <Page warn={true}/>,
  document.getElementById('root')
);

I would recommend this method to comply with React best practices, as outside of codepen you would have different files for different components.

Here's a pen to illustrate: https://codepen.io/paulmartin91/pen/zYGKRNa

hope this helps!

5 Comments

You could also render different components based on conditions, for example this.state.warn ? <Component1 /> : <Component2 />
However, is it possible to (at all) to do somthing like that?
I'm not sure what you mean, could you please elaborate?
is functional component inside a class component is a valid component?
You could put the component in the Render function, outside the return() function and it would also work. I'd always opt for the first method in this case though.
0

I don't think nesting the definition of components like that is idiomatic.

Data can be shared between components using properties.

You can show or hide the banner using a conditional (here, I use the && operator) in your Page component like so:

function WarningBanner({message}) {
    return (<div className="warning">Warning!</div>)
} 

class Page extends React.Component {
  render() {
    return (
      <div>
        { this.props.showWarning && <WarningBanner /> }
      </div>
    )
  }
}

ReactDOM.render(
    <Page showWarning={true} />,
    document.getElementById('root')
)
* {
  font-family: sans-serif;
  margin: 0;
}
button {
  height: 40px;
  width: 200px;
}
.warning {
  background-color: red;
  text-align: center;
  width: 100%;
  padding: 10px;

  font-size: 14pt;
  color: white;
}
<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>

<div id="root"></div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.