I have two basic questions about React:
player
) in a functional component, are the following two approaches the same or are they different in some way?const [player, setPlayer] = useState({})
useEffect(() => {
setPlayer({})
}, []);
player
, the page is eventually updated with values coming from the global store so I need to avoid showing the values of the previous player while the current one is still loading. What is the best way to go about this?Please let me know if you need more background information in order to help.
Thank you in advance!
When assigning initial value directly in useState(initialData)
you are making that state available in the very first render.
On the other hand, if you are setting the initial value in a useEffect
hook, it will be set on mount, but after the very first render.
useEffect(() => {
setPlayer(initialData)
}, [])
If the state variable is important also for the first render, then you should use the first approach. It is also shorter to write and makes more sense.
if you open your devtools when running this example, the debugger
will pause inside the useEffect
and you will see a red circle. Only then the state gets updated which causes the component to re-render.
If you were to edit the code and write useState(initialData)
, you would see the first render did include the correct state when the (when debugger
pauses code execution).
const {useState, useEffect, useLayoutEffect} = React
const App = ({initialData}) => {
const [value, setValue] = useState('🔴')
useEffect(() => {
// at this point, the component has already been rendered
debugger;
// updating the state below will cause a re-render
setValue(initialData)
}, [])
return value
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App initialData={'🟢'} />);
<script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
<div id='root'></div>