Can I change a component's attribute values using a conditional statement in the render function?

Question

Can I change a component’s attribute values using a conditional statement in the render function?

Answer

Absolutely! We can change attribute values of components/elements based on a condition - this functionality is useful in many cases, including changing a className based on a condition.

For example, say we want to render a button and want it to have a different background color based on a condition - to add this functionality to our component we need to set the className attribute value based on said condition like this:

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

class MyButton extends React.Component {
  render() {
    let colorChoice = 'blue';
    let buttonClassName;

    if(colorChoice === 'red'){
      buttonClassName = 'red-button';
    } else {
      buttonClassName = 'blue-button';
    }

    return (
    <button className={buttonClassName}>Here's a button!</button> // the className attribute can be set by injecting JS into our component, in this example className is set based on a condition
    )
  }
};

ReactDOM.render(
  <MyButton />,
  document.getElementById('app')
);

Then in our CSS we would have something like this:

.red-button {
  background-color: red;
}

.blue-button {
  background-color: blue
}
9 Likes

Wait a second?! Does this example mean avoiding writing those particular attributes out in CSS? Or would you still have to define them in the separate CSS document as usual?

1 Like

“Then in our CSS we would have something like this” - this sentence probably seems a bit misleading.
I think we need to have the “background-color” pre-defined for ‘red-button’ and ‘blue-button’ classes in CSS for the attributes to work for the button element that we are rendering.

According to this page, you can also use an inline stylesheet if you would rather not use an external one, and just style the button directly.

example:

class MyButton extends React.Component {
  render() {
    let colorChoice = 'blue';
    let buttonColor;

    if(colorChoice === 'red'){
      buttonColor = {backgroundColor: "red"};
    } else {
      buttonColor = {backgroundColor: "blue"};
    }

    return (
    <button style={buttonColor}>Here's a button!</button>
    );
  }
};
2 Likes

Can’t we use && operator or ternary operations inside JSX

We can. We had learnt about it in an earlier lesson.

1 Like

then why this talk mister

We can use any method to make conditional statements.

In the exercise about conditionals:

Use a Conditional in a Render Function
How might you use a conditional statement inside of a render() function?
Notice that the if statement is located inside of the render function, but before the return statement. This is pretty much the only way that you will ever see an if statement used in a render function.

This works though:

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

const fiftyFifty = Math.random() < 0.5;
// New component class starts here:
class TonightsPlan extends React.Component {
  render() {    
    return (
      fiftyFifty?
        <h1>Tonight I'm going out WOOO</h1>
        :
        <h1>Tonight I'm going to bed WOOO</h1>
    )
  }
};
ReactDOM.render(
  <TonightsPlan/>,
  document.getElementById('app')
);

  • Is a ternary any different from an if-else statement?

Also, from the react docs I read this:

The render() function should be pure, meaning that it does not modify component state, it returns the same result each time it’s invoked, and it does not directly interact with the browser.

If you need to interact with the browser, perform your work in componentDidMount() or the other lifecycle methods instead. Keeping render() pure makes components easier to think about.

So, my question is now: isn’t putting logic inside the render() contradictory to what stated above? A conditional will never result always the same thing. :confused: