UseState in App() uploads everything under App() function?
Asked by Kaldon h about a year ago
I thought useState updates only the state of the element connected to it. However look at this code. Clicking the button randomizes the first sentence (expected) AND the second sentence (supposed to be activated once when app is mounted?)
1import logo from './logo.svg' 2import './App.css' 3import { useState } from 'react' 4 5function App() { 6 const [quote, setQuote] = useState('Great first sentence') 7 8 const quotes = [ 9 "I'm the best man in the world", 10 "I'm strong, patient and persistant", 11 "I've made the best I could at the time with what I knew back then", 12 "I'm a very very lucky creature", 13 ] 14 15 function randomizeQuote() { 16 const randomQuote = quotes[Math.floor(Math.random() * quotes.length)] 17 setQuote(randomQuote) 18 return randomQuote 19 } 20 21 function _randomizeQuote() { 22 const _randomQuote = quotes[Math.floor(Math.random() * quotes.length)] 23 return _randomQuote 24 } 25 26 return ( 27 <div className='App'> 28 <div>{quote}</div> 29 <div>{_randomizeQuote()}</div> 30 <button onClick={randomizeQuote}>Click me </button> 31 </div> 32 ) 33} 34 35export default App
2 Answers
Well React schedules a render every time the state of a component changes. This is often called a re-render
and here's an article going into the whole process of when React re-renders a component.
https://felixgerschau.com/react-rerender-components/#rendering-in-react
In your case, here's what's happening:
On initial load the returned JSX executes and this line
<div>{quote}</div>
outputs Great first sentence (i.e, initial state value that you had set)
while this line
<div>{_randomizeQuote()}</div>
calls the __randomizeQuote()
function which populates the div with a randomized quote.
Now, when a user clicks the Click Me
button, they trigger a state update which re-renders the whole component and so all the JSX in the return is executed again. The lines I've explained above behave the same way and you get 2 randomized quotes!
A possible fix for this is to move the initial randomized quote into state and set its initial to the returnde value of ___randomizeQuote
. Then use that in the returned JSX.
Check this playground out! https://codedamn.com/playground/_sgDdvWsWMl8u3_aG-ayO
Thank you for the detailed answer!