Search code examples
javascriptcssreactjsreactive-programming

React.js - Render Components with Different Styles based on props


So let's say I am creating a simple web layout, where I have a feedback message component above the MainContent component, as so:

class WebLayout extends Component {
  render() {
    <div>
      <Header />
      <FeedBackMessage 
        shouldRenderMessage={true}
        typeMessage={"error"}
        message={"Wrong input!"}
      />
      <MainContent />
    </div>
  }
}

And let's assume that I have different types of messages such as error, warning, success.

Inside the FeedBackMessage, I may have something as so:

class FeedBackMessage extends Component {
  renderMessage(){
    const {shouldRenderMessage, typeMessage, message } = this.props;
    if (shouldRenderMessage === true){
      <div>
        {message}
      </div>
    }
  }
  render(){
    return (
      <div>
        {this.renderMessage().bind(this)}
      </div>
    )
  }
}

I am stumped on how I can render FeedBackMessage styling based on typeMessage prop value.

For instance, if I pass typeMessage with 'error', I like to have the FeedbackMessage component with a red border styling. Or if I pass confirm, I'd like to render with green border.


Solution

  • This all is very dependent on your styling solution.

    If you want to use inline styles it might look something like this:

    class FeedBackMessage extends Component {
      renderMessage(){
        const {shouldRenderMessage, typeMessage, message } = this.props;
        if (shouldRenderMessage === true){
          <div>
            {message}
          </div>
        }
      }
      render(){
        const componentStyle = {
          error: { border: "1px solid red" },
          confirm: { border: "1px solid green" }
        }[this.props.typeMessage];
    
        return (
          <div style={componentStyle}>
            {this.renderMessage().bind(this)}
          </div>
        )
      }
    }
    

    If you want to style with stylesheets, you can use something like classnames to toggle classes based on some logic and then add the class your component.

    class FeedBackMessage extends Component {
      renderMessage(){
        const {shouldRenderMessage, typeMessage, message } = this.props;
        if (shouldRenderMessage === true){
          <div>
            {message}
          </div>
        }
      }
      render(){
        const componentClass = classNames('FeedBackMessage', {
          "error": this.props.typeName === 'error',
          "confirm": this.props.typeName === 'confirm'
        });
    
        return (
          <div className={componentClass}>
            {this.renderMessage().bind(this)}
          </div>
        )
      }
    }
    

    And have a stylesheet like so:

    .FeedBackMessage .error {
      border: 1px solid red;
    }
    
    .FeedbackMessage .confirm {
      border: 1px solid green;
    }