1

Okay, so is there a way to return a value from a function - the way return does - but not stop the function - the way return does?

I need this so I can keep returning values every so often.

My code looks like:

loopingTitleTextHandler = () => {
    const title = ["good", "cool", "887H", "Vertical"];
    for (i = 0; i < 999999; i++) {
        var j = i%4;
        // loopingTitleTextHandler() // calls itself before return terminates execution 
        return title[j]; //return 0,1,2,3 in a loop with 3 second delay
    }
}

My React Component

<ShowTitle size={230}
    title={this.loopingTitleTextHandler()}
    color="#FDA7DC" />

Edit: I'm after a solution that solves this problem in the function like this python answer: Return multiple values over time but using ES6.

import time

def myFunction(limit):
    for i in range(0,limit):
        time.sleep(2)
        yield i*i

for x in myFunction(100):
    print( x )
Anon
  • 1,307
  • 2
  • 20
  • 30

2 Answers2

1

You could make use of setInterval in life-cycle hook. this will repeatedly call the function at an interval

  loopingTitleTextHandler = () => {
        const title = ["good", "cool", "887H", "Vertical"];
        for (i = 0; i < 999999; i++) {
            var j = i%4;
            // loopingTitleTextHandler() // calls itself before return terminates execution 
            return title[j]; //return 0,1,2,3 in a loop with 3 second delay
        }
    }

Add setInerval in componentWillMount(){}

componentWillMount(){
  setInterval(()=>{
      this.loopingTitleTextHandler()
 }, 3000) // 3000 milli seconds, that is 3 sec
 }
Akhil Aravind
  • 5,741
  • 16
  • 35
1

In the context of React, I think it would make more sense to manage these values through state. Assuming you want to return one new title every 3 seconds, you can do the following:

Here's a sandbox: https://codesandbox.io/s/elated-rgb-n4j6z

App.js

import React from "react";
import ReactDOM from "react-dom";
import ShowTitle from "./ShowTitle";

import "./styles.css";

class App extends React.Component {
  state = {
    title: ["good", "cool", "887H", "Vertical"],
    currentTitle: "good"
  };

  loopingTitleTextHandler = () => {
    const { currentTitle, title } = this.state;
    const nextTitleIndex =
      title.indexOf(currentTitle) + 1 === title.length
        ? 0
        : title.indexOf(currentTitle) + 1;

    this.setState({ currentTitle: title[nextTitleIndex] });
  };
  render() {
    return (
      <div className="App">
        <ShowTitle
          changeTitle={this.loopingTitleTextHandler}
          currentTitle={this.state.currentTitle}
        />
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

ShowTitle.js

import React from "react";

class ShowTitle extends React.Component {
  componentDidMount() {
    setInterval(() => {
      this.props.changeTitle();
      console.log(this.props.currentTitle + " " + new Date().getTime());
    }, 3000);
  }

  render() {
    return <div>Title: {this.props.currentTitle}</div>;
  }
}

export default ShowTitle;

In the parent component (App.js) we keep track of the currentTitle. When loopingTitleTextHandler() is called, we update our state.currentTitle with the next title in the array. currentTitle gets passed down to ShowTitle component.

In Child component, we use a setInterval() to call loopingTitleTextHandler() every 3 seconds, and display the next title.

Chris Ngo
  • 15,460
  • 3
  • 23
  • 46
  • This worked, I added a few more details as I am after something that would be applicable in more scenarios. :) – Anon Jul 16 '19 at 11:21
  • @vDog ah I see, I'm not sure of a more reproducible solution, but you definitely could transform this into a hook. and use it in your other components as well. – Chris Ngo Jul 16 '19 at 19:41