Katie
Katie

Reputation: 33

How to generate random number only once every seconds in react native?

The question is very simply yet the solution is quite confusing.

My current implementation is that I'm generating random number between 50 to 100 and save it using this.setState({...}) Which I then call it in my render method.

But the gotcha is that the random method in itself generates random number multiple times. This is because every time the this.setState({...}) is called, the render method renders few times and during this rendering, the random number changes, which is not what I want.

export default class exampleComponent extends Component {
  constructor() {
    this.state = {
      randomNumber: 0
    };
  }

  generateRandomNumber = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;

  myview = () => {
    const { randomNumber } = this.state;

    setInterval(() => this.setState({randomNumber: generateRandomNumber(50, 100)}), 20000);

    return (
      <View>
        <Text>{randomNumber}</Text>
      </View>
    );
  };
  
  render() {
    return(
      <View>
        {this.myview()}
      </View>
    )
  }
}

How can i ensure that the random number doesnt change multiple times after setState() is called?

Upvotes: 1

Views: 6015

Answers (3)

Abinash Gupta
Abinash Gupta

Reputation: 321

Try this.

class Comp extends React.Component {
state = {
      randomNumber: 0
 }

 generateRandomNumber = (min, max) => { 
    const random = (Math.floor(Math.random() * (max - min + 1)) + min)
    console.log("random ", random)
    this.setState({
      randomNumber: random
    })
   }

  render() {
    setTimeout(this.generateRandomNumber.bind(this, 50, 100),1000)
    return(
      <div>
        {this.state.randomNumber}
       </div>
    )
  }
}

codepen : codepen

Upvotes: 0

Stretch0
Stretch0

Reputation: 9251

Do you need to assign the randomly generated number to state? Can you assign it to this.randomNumber or something? It's still available within the react class but just wont cause a re-render

Something like this:

export default class exampleComponent extends Component {
  constructor() {
    super()
    this.randomNumber = 0

    this.generateRandomNumber = this.generateRandomNumber.bind(this)

  }

  newRandomNumber(min, max){
    return Math.floor(Math.random() * (max - min + 1)) + min; 
  }

  generateRandomNumber(){
    setTimeout(() => {
      this.randomNumber = this.newRandomNumber(1, 1000)
    }, 20000)
  }



  myview = () => {

    return (
      <View>
        <Text>{this.randomNumber}</Text>
      </View>
    );
  };

  render() {
    return(
      <View>
        {this.myview()}
      </View>
    )
  }
}

Attempt 2:

I have used javascript to get the element and update the innerHtml without re-rendering the whole component:

class App extends Component {

  constructor() {
    super()
    this.randomNumber = 0

    this.generateRandomNumber = this.generateRandomNumber.bind(this)
  }

  componentDidMount(){
    this.generateRandomNumber() // calls it the first time and the setInterval will keep running
  }

  newRandomNumber(min, max){
    return Math.floor(Math.random() * (max - min + 1)) + min; 
  }

  generateRandomNumber(){
    setInterval(() => {
      document.getElementById("randomNumber").innerHTML = this.newRandomNumber(1, 1000)
    }, 1000)
  }

  render() {

    return (
      <div className="App">

        <div id="randomNumber"></div>

      </div>
    );
  }

}

export default App;

Upvotes: 2

SomethingCool
SomethingCool

Reputation: 303

Why do you use setInterval() this method will keep on giving you random numbers which is not what you want from what i understood?

Just use

setTimeout(function() {
      //your code to be executed after x seconds
    }, delayInMilliseconds);` 

Upvotes: 0

Related Questions