audaz802 audaz802 - 2 months ago 7
React JSX Question

Attaching function to be used as an inline-style to componentWillMount

I'm learning React. I have a small function in vanilla JS that randomly generates a given image. Since its random, and not saved to any state (purposely), each state change also changes image as well, which is what I'm trying to avoid. The image will be used as an inline-style on

<body>
, so it can be used as my background-image.

If I set this
myBackground
function on
componentWillMount
, which renders only once right before component is mounted, then I can accomplish what I need, but I don't know what is expected to be there.

class homePage extends React.Component {
constructor () {
super()
this.state = {}
}

get myBackground () {
const imageArr = ['cat.jpg', 'dog.jpg', 'horse.jpg']
const randomImg = imageArr[Math.floor(Math.random() * imageArr.length)]
const bgImg = {backgroundImage: 'url(' + randomImg + ')'}

return bgImg
}

componentWillMount () {
this.myBackground // doesn't work
}

render () {

// with the current status, below image is changed
// whenever a given state is changed. It needs to be changed
// only right before component is mounted
return <body style={this.myBackground}>
...
}
}


How can I have
this.myBackground
attached to componentWillMount and yet be able to use it inside render? Please note that creating a
setState
to handle this behavior is not expected.

Answer

You're using this.myBackground inside render, which is a getter function. Every time your component re-renders, it is going to call the getter function again and give you another image.

Just change your getter function name to something else and store that into your instance property or state in componentWillMount.

class homePage extends React.Component {
  // Rename your getter function!
  get getNewBackground() {
    const imageArr = ['cat.jpg', 'dog.jpg', 'horse.jpg']
    const randomImg = imageArr[Math.floor(Math.random() * imageArr.length)]
    const bgImg = {backgroundImage: 'url(' + randomImg + ')'}

    return bgImg
  }

  componentWillMount() {
    this.myBackground = this.getNewBackground;
  }

  render() {
    return <body style={this.myBackground}>
  }
}

In all seriousness, you should not be using getter functions like that, your component should look like this:

class HomePage extends React.Component {

  constructor(props) {
    super(props);

    this.state = {
      backgroundImage: this.getNewBackground(),
    };
  }

  getNewBackground() {
    const imageArr = ['cat.jpg', 'dog.jpg', 'horse.jpg'];
    const randomImg = imageArr[Math.floor(Math.random() * imageArr.length)];
    const bgImg = {backgroundImage: 'url(' + randomImg + ')'};

    return bgImg;
  }

  render() {
    return <body style={this.state.myBackground}>
  }
}
Comments