Any idea of how to make the fetched value from Axios will be the initial value of another state?
I'd try to put it on use effect after it renders the state will update
Here is the code:
const [code, setCode] = useState(0);`enter code here`
useEffect(() => {
const result = data[0] ? data[0].code: 0; // <- fetched from axios
setCode(result);
});
you can make api calls and assign those value to your state by making useEffect similar to componentDidMount:
useEffect(() => {
const result = data[0] ? data[0].code: 0; // <- fetched from axios
setCode(result);
},[]);
This will only be called after your first render. I understand you want the api returned value to be your initial state but this is the best way of doing it.
Got it, I'd just put the data[0] into the deps.
Code:
useEffect(() => {
const result = data[0] ? data[0].code: 0;
setcode(result);
}, [data[0]]);
Related
i am using usestate for transfer data. but ufotunately it not quite work.
here is my code:
const [totCons, settotCons] = useState(null)
useEffect(() => {
// declare the async data fetching function
const fetchData = async () => {
// get the data from the api
const data = await fetch('https://piscons2.vercel.app/ConsPiscTotCons');
// convert the data to json
const json = await data.json();
// set state with the result
settotCons(json);
console.log(json)
console.log(totCons)
}
// call the function
fetchData()
// make sure to catch any error
.catch(console.error);;
}, [])
as you can see on image the json return data but the totCons return null.
i did set it settotCons(json)
Updated state will not be available to the state value immedieately.
The react setState is asynchronous, but thats not the only reason for this behaviour. The reason is a closure scope around an immutable const value.
Both props and state are assumed to be unchanging during 1 render.
Treat this.state as if it were immutable.
You can use useEffect to create the sideeffects for totCons
useEffect(() => {
// action on update of totCons
}, [totCons]);
try doing console.log(totCons) outside useEffect.
you will not get the updated value in next line.
you will get the updated value in next render
I expected to get the url with category=business,but the web automatically reset my state to the url that dosent have the category.I dont know the reason behind
let {id}=useParams()
const [newsurl,setNewsurl]=useState(()=>{
const initialstate="https://newsapi.org/v2/top-headlines?country=us&apiKey=c75d8c8ba2f1470bb24817af1ed669ee"
return initialstate;})
//console.log(id);
const [articles, setActicles] = useState([]);
useEffect( ()=>{
if(id === 2)
console.log("condition")
setNewsurl("https://newsapi.org/v2/top-headlines?country=de&category=business&apiKey=c75d8c8ba2f1470bb24817af1ed669ee")},[])
useEffect(() => {
const getArticles = async () => {
const res = await Axios.get(newsurl);
setActicles(res.data.articles);
console.log(res);
};
getArticles();
}, []);
useEffect(() => {
console.log(newsurl)
// Whatever else we want to do after the state ha
s been updated.
}, [newsurl])
//return "https://newsapi.org/v2/top-headlines?country=us&apiKey=c75d8c8ba2f1470bb24817af1ed669ee";}
return (<><Newsnavbar />{articles?.map(({title,description,url,urlToImage,publishedAt,source})=>(
<NewsItem
title={title}
desciption={description}
url={url}
urlToImage={urlToImage}
publishedAt={publishedAt}
source={source.name} />
)) } </>
)
one more things is that when i save the code the page will change to have category but when i refresh it ,it change back to the inital state.Same case when typing the url with no id.May i know how to fix this and the reason behind?
Setting the state in React acts like an async function.
Meaning that the when you set the state and put a console.log right after it, it will likely run before the state has actually finished updating.
You can instead, for example, use a useEffect hook that is dependant on the relevant state in-order to see that the state value actually gets updates as anticipated.
Example:
useEffect(() => {
console.log(newsurl)
// Whatever else we want to do after the state has been updated.
}, [newsurl])
This console.log will run only after the state has finished changing and a render has occurred.
Note: "newsurl" in the example is interchangeable with whatever other state piece you're dealing with.
Check the documentation for more info about this.
setState is an async operation so in the first render both your useEffetcs run when your url is equal to the default value you pass to the useState hook. in the next render your url is changed but the second useEffect is not running anymore because you passed an empty array as it's dependency so it runs just once.
you can rewrite your code like the snippet below to solve the problem.
const [articles, setActicles] = useState([]);
const Id = props.id;
useEffect(() => {
const getArticles = async () => {
const newsurl =
Id === 2
? "https://newsapi.org/v2/top-headlines?country=de&category=business&apiKey=c75d8c8ba2f1470bb24817af1ed669ee"
: "https://newsapi.org/v2/top-headlines?country=us&apiKey=c75d8c8ba2f1470bb24817af1ed669ee";
const res = await Axios.get(newsurl);
setActicles(res.data.articles);
console.log(res);
};
getArticles();
}, []);
Every Time i try to refresh the page it returns to 0.
I'm taking the bestScore from turns when the match is equal to 6,
so basically everytime the matched cards hit 6 it will take the bestScore from the turns and save the bestScore to localStoarge and it works but when i try to refresh its gone
function App() {
const [cards, setCards] = useState([]);
const [turns, setTurns] = useState(0);
const [match, matchedCards] = useState(0);
const [bestScore, setBestScore] = useState(
localStorage.getItem("highestScoresss")
);
const [choiceOne, setChoiceOne] = useState(null); //Kullanici 1.karta basinca setChoiceOne o karti alacak ve guncelliyecek
const [choiceTwo, setChoiceTwo] = useState(null); //Kullanici 2.karta basinca setChoiceTwo o karti alacak ve guncelliyecek
const [disabled, setDisabled] = useState(false);
useEffect(() => {
if (match === 6) {
const highScore = Math.min(turns, bestScore);
setBestScore(highScore);
setBestScore(turns);
} else {
console.log("false");
}
}, [turns]);
useEffect(() => {
localStorage.setItem("highestScoresss", JSON.stringify(bestScore));
});
This Is the JSX
<div className="bilgi">
<p>Sıra: {turns}</p>
<p>Bulunan: {match}</p>
<p>En iyi Skor: {bestScore}</p>
<button onClick={shuffleCards}>Yeni Oyun</button>
</div>
</div>
The issue with your implementation is that you set state to 0 first, and then the useEffect hook runs and sets localStorage to the state value.
If you are potentially initializing your state to a value stored in localStorage then I suggest using a lazy initialization function so the initial state value is set before the initial render and eliminates the need for the additional useEffect hook to set state from storage. This reads from localStorage and returns the parsed value, or 0 if the parsed result is null or undefined.
const initializeState = () => {
return JSON.parse(localStorage.getItem("highestScoresss")) ?? 0;
};
...
const [bestScore, setBestScore] = useState(initializeState());
You will want to use a dependency array on the useEffect that is persisting the "highestScoresss" value in localStorage such that it only triggers when the bestScore state value updates and not on each and every render.
useEffect(() => {
localStorage.setItem("highestScoresss", JSON.stringify(bestScore));
}, [bestScore]);
After looking at the Code image, I think that you want that the bestScore to be set in the local storage with the key highestScores.
Your current useEffect hook implementation lacks a dependency array. You want that the localStorage should be updated every time a new bestScore is set.
For that add bestScore to the dependency array.
useEffect(() => /* YOUR OPERATION*/, [any_dependency])
Also, I recommend that you look at your first useEffect implementation again. You seem to be setting the bestScore state twice. Once with highScore and then with turns.
Recommended Reading
About Dependency Array - ReactJS Docs
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
I have a get request in react application
I get the values from that request using: const dataFromReq = selector.data;
When i make: console.log(dataFromReq), in my component i get all values. But, i want to set the dataFromReq to another state. For this i made: const [anotherState, setAnotherState] = useState(dataFromReq), and now i expect when i will do: console.log(anotherState), to display my values, but it does not work and i get an empty array.
I know that useState is asynchronous but, how to get the value in console.log(anotherState)?
Use useEffect to update some state
const SomeComponent = () => {
useEffect(() => {
if (selector && selector.data) {
setAnotherState(selector.data)
}
}, [selector]);
}