This question already has answers here:
The useState set method is not reflecting a change immediately
(15 answers)
Closed 25 days ago.
Currently experiencing problem, tham I'm not able to assign state to useState const varaible.
const [account, setAcc] = useState({});
const [logged, setLogg] = useState(false);
useEffect(() => {
console.log("app");
let jwt = localStorage.getItem("jwt");
let username = localStorage.getItem("username");
console.log(username + jwt);
const API_URL = "https://localhost:7129/api/Users/ByUsername?username=";
if (jwt != "" && username != "") {
axios
.get(API_URL + username, {
headers: authHeader(),
})
.then((res) => {
console.log("passed");
console.log(res.data);
setAcc(res.data);
console.log(account);
setAccount(res.data);
console.log(account);
setLogged();
redirect("/index/");
})
.catch((res) => {
if (res.status == 401) {
setLogout();
localStorage.removeItem("jwt");
localStorage.removeItem("username");
redirect("/login/");
}
});
}
}, []);
function setAccount(param) {
console.log(param);
setAcc(param);
}
As you can see in console image I've attached, I set console log commands on every step. When comes to finished GET i will show in output "passed", then it will print in output response.data and then it will try to set state through method.
console
The problem is that the code doesn't actually set the state. It only logs the value to the console.
To fix this, you need to use the setAcc() method to set the value of the account state variable.
Related
This question already has answers here:
The useState set method is not reflecting a change immediately
(15 answers)
Closed 11 months ago.
I have a simple page editor, When a user clicks edit page it opens an editor. I am passing the ID of the page using redux which will be used to get data from API.
Here is my Editor.
const [pageData, setPageData] = useState("");
const getPage = async (id) => {
try {
const response = await api.get(`/landing_pages/${id}`);
console.log("page", response.data); // displays data at the end
setPageData(response.data);
} catch (error) {
console.log(error);
}
};
useEffect(() => {
getPage(pageID);
console.log('Page Data', pageData) // displays nothing
let LandingPage = pageData;
const editor = grapesjs.init({
container: "#editor",
components: LandingPage.components || LandingPage.html,
})
}, [pageID, getPage])
Why is Page Data display nothing even though the data from API is returned and is displayed in the console at the end? what am I doing wrong here?
Even if you await your getPage call, the updated pageData won't be available until the next render cycle so your assignment to LandingPage will be one cycle behind.
You should instead update in one useEffect and watch for changes to pageData in another.
const [pageData, setPageData] = useState("");
useEffect(() => {
const getPage = async (id) => {
try {
const response = await api.get(`/landing_pages/${id}`);
console.log("page", response.data); // displays data at the end
setPageData(response.data);
} catch (error) {
console.log(error);
}
};
getPage(pageID);
}, [pageID]);
useEffect(() => {
console.log('Page Data', pageData); // displays updated pageData
let LandingPage = pageData;
const editor = grapesjs.init({
container: "#editor",
components: LandingPage.components || LandingPage.html,
});
}, [pageData]);
This question already has answers here:
React setState not updating state
(11 answers)
setTimeout function in useEffect outputs a cached state value
(1 answer)
Closed 11 months ago.
I have a react app which basically wants to give some special permission if the logged in user is an admin. For this i have a table in the db where I store all administrator emails.
I have an UseEffect which I use to verify the current logged in user if it is available in the admin user db.
useEffect(() => {
const getUsers = async () => {
const data = await getDocs(adminUsersCollectionRef);
console.log(data);
const user = data.docs.find((x) => x.data().email === currentUser.email);
console.log(user.data());
if (user && user.data()) {
console.log("inside if")
setIsAdmin(true);
}
setTimeout( () => {console.log("Admin este :" + isAdmin)}, 2000);
};
getUsers();
}, []);
My problem is the following:
const [isAdmin, setIsAdmin] = useState(false); my isAdmin state will always be false, even if I explicitly set it inside my if condition.
Thank you in advance!
I have this piece of code that is connecting to metamask wallet and sets the account address using useState().
const [currentAccount, setCurrentAccount] = useState("")
const connectWallet = async () => {
try {
if (!ethereum) return alert("Please install MetaMask.")
const accounts = await ethereum.request({ method: "eth_requestAccounts" })
setCurrentAccount(accounts[0])
console.log(accounts)
// TODO:Add conditional statement to check if user has token
navigate("/portfolio")
} catch (error) {
console.log(error)
throw new Error("No ethereum object")
}
}
console.log("current account", currentAccount)
const returnCollection = async (currentAccount) => {
const options = { method: 'GET', headers: { Accept: 'application/json' } };
fetch(`https://api.opensea.io/api/v1/collections?asset_owner=${currentAccount}&offset=0&limit=300`, options)
.then(response => response.json())
.then(response => console.log("collection owned by current address", response))
.catch(err => console.error(err));
useEffect(() => {
returnCollection(currentAccount)
})
The console is logging the account but when I try to pass it in the returnCollection call in useEffect() it comes back as undefined.
It seems here, you are doing something like this:
useEffect(() => {
returnCollection(currentAccount)
})
This will run after every rerender or every state change, and also initially when the component is first mounted, when currentAccount is "". Initially, current account is "", so you may not want to get the collection from "". Instead, maybe what you can do is create another state variable for the result of the returnConnection, and set the state variable to the result of the returnConnection, since you typically don't return results from useEffect, unless it's a cleanup function. Also, maybe you can check the state of currentAccount inside of the useEffect to make sure it's not "", before returning the result.
The JSON response is as shown in the image 1.
I was able to assign the entire response using axios (which already does the JSON.parse) to the state (named profile).
while profile.bio and profile.image are working;
profile.user.username, etc are not working and throwing an error - Undefined is not an object
const [profile, setProfile] = useState({});
const phone_no = phone.phone;
const fetchProfile = useEffect(() => {
var res = {};
axios
.get('<API URL>' + phone_no)
.then((response) => (res = response.data))
.then(() => {
setProfile(res);
})
.then(() => console.log(profile))
.catch((e) => console.log(e)); });
const user_stream = {
name: first.first_name,
image: profile.image,
id: profile.user.id,
};
Update - Solution: Using async-await with axios, it's fixed.
profile or profile.user may still be undefined when trying to access it, so profile.bio is just undefined so it doesn't cause an error, but profile.user.username tries to access a property of an undefined object.
Try adding profile?.user?.username
Or profile && profile.user && profile.user.username
This will ensure that it only tries to render the username if profile is already defined
This question already has answers here:
The useState set method is not reflecting a change immediately
(15 answers)
Closed 2 years ago.
hey all so im using react-natives-community async storage and i can't for the life of me get the state to save and im not too sure why. the first console.log from the await variable returns the correct information, but when i set the state the second console.log returns null and im not sure what's going on
const [userEmail, setUserEmail] = useState<string | null>(null);
const getEmail = await AsyncStorage.getItem('email')
console.log(getEmail + 'first')
setUserEmail(getEmail);
console.log(userEmail + 'second')
I made this custom hook but still no luck
const useGetAsyncStorage = (AsyncStorageItem: string): string => {
try {
const [data, setData] = useState<string | null>(null);
useEffect(() => {
const fetchAsyncStorage = async () => {
const AsyncStorageData = await AsyncStorage.getItem(AsyncStorageItem);
console.log(AsyncStorageData)
setData(AsyncStorageData);
};
fetchAsyncStorage();
}, [AsyncStorageItem]);
return data as string
} catch (error) {
return error
}
};
The thing is state updates are asynchronous. You will end up seeing the null for the email what it was initially . If you want to see the change , you should do console.log in useEffect() hook