console log the state after using useState doesn't return the current value
useState
by default simply does one thing and one thing only, set the new state and cause a re-render of the function. It is asynchronous in nature so by default, methods running after it usually run.
From your example, on a fresh load of the page, typing 's' causes useState to change the state, but because it is asynchronous, console.log
will be called with the old state value, i.e. undefined
(since you didn't set a value. You should consider setting an initial state, if you want to)
const [weather, setWeather] = useState(''); // Set the intial state
The only way to truly read the value of the state is to use useEffect
, which is called when there is a re-render of the component. Your method simply becomes:
import React, { useEffect, useState } from 'react';
import ReactDOM from 'react-dom';
function Weather() {
const [weather, setWeather] = useState('');
useEffect(() => console.log(weather), [weather]);
const changeValue = event => setWeather(event.target.value);
return <input value={weather} onChange={changeValue} />;
}
const rootElement = document.getElementById('root');
ReactDOM.render(<Weather />, rootElement);
useState console log return undefined
Without a working code example which shows the issue it's hard to see why your console isn't outputting the correct value.
Here's a working example where the console outputs light
.
import React, { useState } from "react";
import ReactDOM from "react-dom";
const App = () => {
const [moduleConfig, setModuleConfig] = useState("");
const handleClose = (e, moduleConfig) => {
setModuleConfig(moduleConfig);
};
console.log("moduleConfig:", moduleConfig);
return <button onClick={e => handleClose(e, "light")}>Click me</button>;
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Codesandbox link
How do I console log the value of initialized useState in react?
As you are using the functional components, you could set your state or put console.log into the useEffect() hook. Also, you could call your own function in this functional component to do the same. I am writing out both the scenarios in the below code snippet.
import React,{useEffect,useState} from 'react';
export default function IntroToReact(){
const initialValues = {bag: 32,donor:""};
const [values, setValues] = useState(initialValues);
//Effect is called once during init
useEffect(()=>{
console.log(values.bag);
},[]);
//Effect is called everytime the values change
useEffect(()=>{
console.log(values.bag);
},[values]);
// Display the values
function onChangeValues(){
console.log(values.bag)
}
return (
<div>
{onChangeValues()}
</div>
);
}`
For further understanding, this concept you could refer to the official website of the react:- https://reactjs.org/docs/hooks-effect.html
I hope it will help you.
Thank you :)
Console.log() after setState() doesn't return the updated state
setState()
is async (React docs), so the state changes won't be applied immediately. If you want to log out the new state,setState()
takes in a function as the second argument and performs that function when the state is updated. So:
this.setState({
abc: xyz
},
() => console.log(this.state.abc),
)
Or you can also use componentDidUpdate()
, which is recommended
The useState set method is not reflecting a change immediately
Much like .setState()
in class components created by extending React.Component
or React.PureComponent
, the state update using the updater provided by useState
hook is also asynchronous, and will not be reflected immediately.
Also, the main issue here is not just the asynchronous nature but the fact that state values are used by functions based on their current closures, and state updates will reflect in the next re-render by which the existing closures are not affected, but new ones are created. Now in the current state, the values within hooks are obtained by existing closures, and when a re-render happens, the closures are updated based on whether the function is recreated again or not.
Even if you add a setTimeout
the function, though the timeout will run after some time by which the re-render would have happened, the setTimeout
will still use the value from its previous closure and not the updated one.
setMovies(result);
console.log(movies) // movies here will not be updated
If you want to perform an action on state update, you need to use the useEffect
hook, much like using componentDidUpdate
in class components since the setter returned by useState
doesn't have a callback pattern
useEffect(() => {
// action on update of movies
}, [movies]);
As far as the syntax to update state is concerned, setMovies(result)
will replace the previous movies
value in the state with those available from the async request.
However, if you want to merge the response with the previously existing values, you must use the callback syntax of state updation along with the correct use of spread syntax like
setMovies(prevMovies => ([...prevMovies, ...result]));
Related Topics
How to Calculate Md5 Hash of a File Using JavaScript
How to Return Values from Async Functions Using Async-Await from Function
Chrome Extension - Sendresponse Not Waiting for Async Function
Preventdefault() on an <A> Tag
What Does the @ Mean Inside an Import Path
How to Get a Url Parameter in Express
How to Prevent Your JavaScript Code from Being Stolen, Copied, and Viewed
React Hooks Usestate() with Object
Detecting When a Div's Height Changes Using Jquery
Console Log the State After Using Usestate Doesn't Return the Current Value
How Does Variable Assignment Work in JavaScript
Object Method with Es6/Bluebird Promises
How to Get Selected HTML Text with JavaScript