Random Quote Machine setQuote and setAuthor

Tell us what’s happening:
Describe your issue in detail here.
I am building my random quote machine in ReactJS along with bootstrap. I thought I had it complete as it was generating random quotes when i pressed the button and also a random author. but the author does not match the actual author of the quote. I know why, it’s because I have called a props.quotes[randomIndex()] to set both my quote and my author so it runs the random index twice. my question, is How do I prevent this from happening. like tie the props.quotes[i].author index to the same randomIndex() call I have for getting the quote.

Your code so far
const QuoteBox = (props) => {

 const [text, setQuote] = useState(props.quote)

 const [author, setAuthor] = useState(props.author) 

 let randomIndex = () =>{

    return Math.floor(Math.random() * props.quotes.length)

   }

    

 const clickQuoteHandler = () => {

    setQuote(props.quotes[randomIndex()].quote);

    setAuthor(props.quotes[randomIndex()].author);

}

return (

    <div className="quote-box card col-md-4" id="quote-box">

        <h1 className="card-header">Quote Machine!</h1>

        <Quote quote={text} />

        <Author author={author} />

        <div className="btn-group">

            <button onClick={clickQuoteHandler} className='btn btn-primary' id='new-quote'>New Quote</button>

            <Tweet quote={text} author={author} />

        </div>

    </div>

)

}

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0

Challenge: Build a Random Quote Machine

Link to the challenge:

 const clickQuoteHandler = () => {
    setQuote(props.quotes[randomIndex()].quote);
    setAuthor(props.quotes[randomIndex()].author);
}

You are generating two different random indices. You want them to both have the same index - you want to call that function once in that callback function, and use the same one for each. The other option would be to store the index in state and not store the quote and author, but just use the index to access them when needed. The first option would be easier to implement with what you have.

1 Like

That is what I figured was the problem. I just have not been sure how to tie them together.
what has seemed to work was to change the handler to this

const clickQuoteHandler = () => {
         let index = randomIndex()
        setQuote(props.quotes[index].quote);
        setAuthor(props.quotes[index].author);
    }

they are now synced up, but this still seems wrong. would I not still be calling two instances of randomIndex()? sorry. I’m just a little confused. I prefer to do it correctly and not just keep it this way because it “works”

EDIT
is it not calling randomIndex() twice because I have it set to the index so that when clickQuoteHandler is called it calls the randomIndex() just once and assigns the return value to index?

The onClick handler clickQuoteHandler runs one time when you click the button. Any function invocation inside it will run however many times you invoke that function. Initially, you ran it twice, now you only run it one time.

randomIndex just returns a new number each time you call it. If you need the same number in two places you just use its return value by storing it like you are now. If you run it twice it will return two different numbers.

2 Likes