when I try to upload an image on firestore I get the url but it is not stored in the firestore database - reactjs

const CreatePost = async () => {
if (imageUpload == null) return;
const imageRef = ref(storage, `images/`);
uploadBytes(imageRef, imageUpload).then((snapshot) => {
getDownloadURL(imageRef).then((url) => {
setImageUrl(url);
console.log(url);
});
});
console.log(url) Works and gives me the correct url but it is not stored in firestore

React useState hook is asynchronous. So, it won't have the URL that you are setting at the time when you're using it. Use the useEffect hook and add your state in the dependence array, and you will always get the updated value.

Related

How do i put a setstate function that is already within an async function, within a useEffect hook?

I am working on a project, which is a django project with REACT as the frontend. For the homepage, there is a useState variable ('room_code') that is used. The setstate variable is set_room_code. So, i have an async function that fetches the room code from an api and then the idea is to use the set_room_code hook. But this is just not working. The issue is with the set_room_code as the code works if i simply remove it. I have tried to search up ideas but i am short on it. Any input would be appreciated.
useEffect( () => {
let fetch_code = async () => {
const response = await fetch('/api/user-room');
const data = await response.json();
console.log('hi');
console.log(data.room_code);
console.log('bhao');
set_room_code(data.room_code);
};
fetch_code();
console.log(hi);
}, []);
I have tried using an extra useEffect hook but that doesnt work as well
A few things, first its best practice to name the useState variable
const [roomCode, setRoomCode] = useState();
FYI.
Now as to your question--
useEffect( () => {
let fetch_code = () => {
fetch('/api/user-room').then((data) => {
setRoomCode(data.room_code);
console.log(data.room_code);
return response.json();
});
};
fetch_code();
console.log("this should show your RoomCode", roomCode)
}, [roomCode]);

React does not wait for async function before mounting components

I am currently using a mock json-server to hold user information in my React app. I am working on storing settings and preferences for users. I have a setting page implemented through a Route component. I am displaying the settings configurations on this page. I am fetching the user settings in App.tsx :
const fetchUser = async (id:number) => {
const res = await fetch(`http://localhost:5001/users/${id}`)
const user = await res.json()
return user
}
const getSettings = async () => {
const user = await fetchUser(0)
setSettings(user.settings);
}
Then I am passing down the state variable for settings through useContext.
const [settings, setSettings] = useContext(userContext);
This works fine when I start on the root page and then go to the settings. However, if the user goes directly to the settings page, the setting state is initially null and I cannot access its values. I tried to fetch the settings again in the setting page component with useEffect but React does not wait for async functions to complete before mounting the components.
const getSettings = async (id:number) => {
const res = await fetch(`http://localhost:5001/users/${id}`)
const user = await res.json()
const settings = user.settings
setSettings(settings);
}
useEffect(() => {
if (!settings) getSettings(0);
}, [])
Is there a way to get around this? I would like to access the settings state throughout the app but the user should not have to start with the root component.
Note: It does work if I check that the value is null before use like this :
settings?.test.difficulty
Please try the below change for useEffect:
useEffect(async () => {
if (!settings) await getSettings(0);
}, [])

Update array using useState

I'm calling an API inside the useEffect hook and trying to update my state covidData but my array remains empty even after calling the setData function:
const [covidData, setData] = useState([]);
useEffect(() => {
async function getGlobalData() {
let response = await fetch('https://api.covid19api.com/summary');
let jsonResponse = await response.json();
const globalData = jsonResponse.Global;
//setting covidData
setData([...covidData, {recovered: globalData.TotalRecovered}])
console.log(covidData); //covidData is empty
}
getGlobalData()
}, [])
what am I doing wrong?
Your code is correct, the state is updated asynchronously, it's normal your console.log will not display your state after your setState.
It is how react works, when you change state of something, react creates new instance of virtual dom.
So when you change state of covidData the value you set will be in new instance and the console.log is still in that old instance so it logs old value which is empty as you set when using useState.
Try logging with button onClick event and you will see your data or you can check with React Dev Tools
Also you can refactor your code as
useEffect(async () => {
let response = await fetch('https://api.covid19api.com/summary');
let jsonResponse = await response.json();
const globalData = jsonResponse.Global;
//setting covidData
setData([...covidData, {recovered: globalData.TotalRecovered}])
}, [])
More on virtual dom
React Docs
What is virtual DOM

React Hook Initializing the state with server call

Working with a react component using hooks. I am attempting to assign values to my state after an Axios call. The data is correctly returned and it appears the state is correctly updated; however, the DOM is not updating with the values. Is this the proper method for doing this?
export const Main = (props) => {
const { token } = useParams()
const [user,setUser] = useState({name:""})
useEffect(()=>{
const getUser = async() =>{
const response = await API.post("usrinfo",{token:token})
setUser({name:response.data.name});
}
getUser()
},[token])
return(
<div className="main-header">{user.name}</div>
);
}
Found the issue:
AXIOS returns a data portion in it's response so instead of response.data.name it should be response.data.data.name.
Thanks for all your responses.

react native lazy initial state from asyncstorage

I try to get a string from asyncStorage and set it as initial state in a functional component.
I found in the documentation that we can provide a function like initial state. I tried some solutions with asyncStorage and sqlite and don't get results. This is some code, What is wrong and is there some other solution for storing active theme in storage.
const retrieveData = async () => {
try {
const value = await AsyncStorage.getItem("theme");
return value;
} catch (error) {}
};
const [isTheme, setIsTheme] = useState(retrieveData);
useEffect(() => {
AsyncStorage.setItem("theme", isTheme);
}, [isTheme]);
I think retrieveData is still a promise. You should get the value by doing await(retrieveData)

Resources