0

Below is a snippet of my code.. I'm working on a random quote generator and would like to find a solution on generating each random quote and background from the arrays without repeats until all have been used, and then cycling through again. The background images are being imported directly into the state and the quote array is imported from a separate file. I've attempted slicing each item from the array and pushing it into an empty one, but so far that has been unsuccessful.

   constructor(props) {
        super(props);
        
        this.state = {
            quote: quotes[0].quote,
            author: quotes[0].author,
            backgrounds: [
                photos..
            ]
        };
    }
    
    
    shuffleAll = (arr) => {
        return arr.sort(function () { return 0.5 - Math.random() });
    }
    
    findRandomQuote = (arr) => {
        let num = Math.floor(Math.random() * quotes.length);
        let randQuote = quotes[num];
        this.shuffleAll(quotes);
        this.setState({
            quote: randQuote.quote,
            author: randQuote.author
        });
    }

    findRandomBackground = (arr) => {
        const { backgrounds } = this.state;
        let background = backgrounds[Math.floor(Math.random() * backgrounds.length)];
        this.shuffleAll(backgrounds);
        document.body.style.background = `url(${background})`;
    }
3
  • What is quotes? Please try creating a minimal reproducible example Commented Apr 30, 2021 at 15:16
  • "I've attempted slicing each item from the array and pushing it into an empty one" - Please also share the code that you've attempted Commented Apr 30, 2021 at 15:20
  • quotes is being imported in from a separate file holding my quotes array, which has both the quote and author in each index. previously I have tried adding another item to state such as usedQuotes = [ ] , and then after setting state I added quotes.slice(randQuote).push(this.usedQutoes) to the function findRandomQuote, but that did not work. Commented May 18, 2021 at 20:08

1 Answer 1

1

You can use state to store the quote array, and substract from it until all quotes are used up:

constructor(props) {
    super(props);
    this.state = {
        availableQuotes: [...quotes],
        activeQuote: null
    };
}

findRandomQuote = () => {
    const quoteOptions = this.state.availableQuotes.length > 0 ? this.state.availableQuotes : quotes;
    const randomIndex = Math.floor(Math.random() * quoteOptions.length);
    this.setState({
        availableQuotes: [...quoteOptions].splice(randomIndex, 1),
        activeQuote: quoteOptions[randomIndex]
    });
}


// This runs after component mounts, to set the first random quote
componentDidMount() { 
    this.findRandomQuote();
}

You can do a similar thing to randomise the background images.

Sign up to request clarification or add additional context in comments.

1 Comment

I haven't quite gotten this solution to work with my code, but adding componentDidMount fixed another issue I've had with rendering the first random quote on page load, so thank you!!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.