0

I'm working on part 1 of Fullstack Open, the Anecdotes exercise, and I can't figure out why a function is firing when the button I'm pressing is not supposed to trigger that function. You'll see below, I created a generateRand function that generates a random number no greater than the length of the anecdotes array. The handleNext function calls generateRand and sets the state of selected to the value of generateRand in order to pick an anecdote from the array. A separate function, handleVote, allows the user to vote for the current anecdote. I'm not sure why when I press vote, it fires generateRand when handleVote is the function that gets called when I press the vote button.

App.js

import React, { useState } from 'react'

const Button = ({ handleClick, text }) => {
    return (
        <button style={{ margin:'5px' }} onClick={handleClick}>
        {text}
        </button>
    )
}

const Anecdote = ({ anecdotes, selected }) => {
    return (
        <div>
            {anecdotes[selected]}
        </div>

    )
}

const App = () => {
    const anecdotes = [
        'If it hurts, do it more often',
        'Adding manpower to a late software project makes it later!',
        'The first 90 percent of the code accounts for the first 90 percent of the development time...The remaining 10 percent of the code accounts for the other 90 percent of the development time.',
        'Any fool can write code that a computer can understand. Good programmers write code that humans can understand.',
        'Premature optimization is the root of all evil.',
        'Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.'
    ]
   

    const [selected, setSelected] = useState(0)
    // const [trackVotes, setVote] = useState([])
    const [points, setPoints] = useState({0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0})

    // Generate random number
    const generateRand = () => {
        const max = anecdotes.length
        const random = Math.floor(Math.random()* max)
        console.log('generateRand fired')
        return random
    }

    const handleNext = () => { 
        setSelected(generateRand()) 
        console.log('handleNext fired.')
  }

    const handleVote = () => {
        const copy = { ...points }
        copy[selected] += 1
        setPoints(copy)
        console.log('handleVote fired.')
    }
    

  return (
    <div>
      <Anecdote anecdotes={anecdotes} selected={generateRand()}/>
      <Button handleClick={handleVote} text="vote"/>
      <Button handleClick={handleNext} text="next anecdote"/>
    </div>
  )
}

export default App

1 Answer 1

2

generateRand() is called on every render because you have passed it like this.

<Anecdote anecdotes={anecdotes} selected={generateRand()}/>

So whenever you click the vote button, it triggers handleVote in which you setPoints, leading to re-render and hence calling generateRand() again

You should change this to

<Anecdote anecdotes={anecdotes} selected={selected}/>
Sign up to request clarification or add additional context in comments.

Comments

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.