set state not working react hooks(string) asyncStorage [duplicate] - javascript

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

Related

useState won't set state React Vite [duplicate]

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.

Get data using useeffect hook in react js [duplicate]

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]);

React state is always false even if it set explicitly [duplicate]

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!

Console log inside React 'useEffect' function doesn't work after page refresh [duplicate]

This question already has answers here:
The useState set method is not reflecting a change immediately
(15 answers)
Closed 1 year ago.
The 'useEffect' function is being used to retrieve data and then store it in the 'ratings' array. I'm currently trying to loop through the 'ratings' array elements in order to console log their contents. This works when the component is first mounted but stops working once the page is refreshed. I found that I can get it to work by placing the 'forEach' outside the useEffect function but was wondering why it doesn't work inside the function and if there's another solution.
const Rating = ({id}) => {
let url=`https://api.jikan.moe/v3/anime/${id}/stats`;
const [ratings, setRatings] = useState([]);
useEffect(() =>
{
(async function()
{
try{
const res = await axios.get(url);
setRatings(Object.values(res.data.scores));
if (ratings) ratings.forEach((rating)=>{console.log(rating.votes)}); //Doesn't work after refresh
}
catch(err)
{
console.log(err);
}
})();
}, [url])
...
}
export default Rating;
When you do setRatings(Object.values(res.data.scores));, the ratings state is not updated imediatelly, so if (ratings) is still the empty array when the app runs if (ratings) ....
Do something like this instead:
const scores = Object.values(res.data.scores);
setRatings(scores);
if (scores) scores.forEach((rating)=>{console.log(rating.votes)});
or use another useEffect for the ratings so it runs when it gets updated:
useEffect(() => {
if (ratings) ratings.forEach((rating)=>{console.log(rating.votes)});
}, [ratings]);

React state not rendering after is has been changed [duplicate]

This question already has answers here:
Using async/await with a forEach loop
(33 answers)
console.log of element.children shows 0 length but has three entries when expanded later
(1 answer)
Closed 1 year ago.
I am using Firebase in this component to retrieve an array of some basic user details. The array size is always 3 with this query. The function that carries out this action is whoToFollow() and when the results are received the function updates a state variable 'who' There is no array mutation happening here. I simply reset the state to the returned value.
Unfortunately despite confirming that the state has indeed been updated, the component does not re-render to display this. In order to simplify the code I have only used the length of the array as the value to be displayed.
Below the code I have included a screenshot of the console logs which display the code execution steps and shows a confirmation of the state value being changed. (returned data is made up test data)
const storage = getStorage(firebaseApp);
const db = getFirestore();
function Aside() {
const [who, setWho] = useState([])
const whoToFollow = async () => {
const usersRef = collection(db, "users");
const q = query(usersRef, limit(3));
const querySnapshot = await getDocs(q);
const results = await querySnapshot.docs.map(doc => doc.data());
let filteredArray = []
results.forEach(async (user) => {
let imgPath = await getDownloadURL(ref(storage, user.profilePicture));
let tmpObj = {
uid: user.UID,
displayName: user.displayName,
userName: user.userName,
profilePicture: imgPath
};
filteredArray.push(tmpObj);
});
console.log('Users recieved and updating who state')
setWho(filteredArray)
}
useEffect(() => {
console.log('component did mount, calling "WhoToFollow()" function')
whoToFollow()
}, []);
useEffect(() => {
console.log('who state has been updated but nothing is being rendered?')
console.log(who)
}, [who]);
return (
<aside>
<div className='aside-head'>Search</div>
<div className='aside-cont'>
<div className='who-to-follow'>
<div className='wtf-head'>
New users to follow
</div>
<div className='wtf-list'>
{who.length}
</div>
</div>
</div>
</aside>
);
}
export default Aside;

Categories

Resources