I wonder is this expected or not, but everytime i do refetch the result or onResult is called twice.
const {onResult,refetch}=useQuery(GQLendpoint,options)
onResult(data=>{
console.log(data)})
const refetchData = (newOptions)=>{
refetch(newOptions)}
every time the refetch called, the onresult is called twice. I've tried to use fetchPolicy, nextFetchPolicy to network-only/no-cache but the onResult is still called twice.
Related
I'm having trouble with React Native showing wrong value for me. I wan't to show the value after an useState update. My goal is to pass the value to the parent component but right now it passes the opposite value (true when switch is off). What do I have to do to console.log the right value after a useState update?
Watch image for example here
The useState hook is somewhat asynchronous (although you cannot wait for it).
Try using a useEffect:
useEffect(() => {
console.log(isEnabled)
}, [isEnabled]) // Array of dependencies: when any of these value changes, the function in the useEffect will re-run
More information here:
https://dev.to/shareef/react-usestate-hook-is-asynchronous-1hia
https://javascript.plainenglish.io/why-you-shouldnt-always-use-usestate-658994693018
The Change function will always "see" the state value that existed at the time of running the function. This is not because of asynchronicity per se (state updates are actually sync) but because of how closures work. It does feel like it is async though.
The state value will properly update in the background, but it won't be available in the "already-running" function. You can find more info here.
The way I see your handler implemented though:
const handleChange = () => {
setIsEnabled(!isEnabled) // you do not need updater function, you can directly reference the state
triggerParentMethod(!isEnabled); // then you can also directly call the parent function here
}
I recommend this as this way you will notify the parent immediately on user click instead of waiting for the state to be set and then notifying the parent in the next render cycle (in the effect), which should be unnecessary.
State updates in React are asynchronous, meaning that React does not wait for the state to be updated before executing the next line of code. In your case, the state update setIsEnabled(...) is not finished before console.log(isEnabled) is run, and therefore it returns the old value.
Just put the console.log(isEnabled) outside the function for it to print the update correctly. The component SetupSwitch is re-rendered when the state isEnabled is updated, which means it prints the console.log of the updated variable again.
...
console.log(isEnabled);
const Change = () => {
...
You will have to implement useEffect to view the changes.
useState is an asynchronous function it will go to the callback queue, meanwhile, the value will be consumed, so you need to trigger the action whenever the count changes. (for this example)
const [count, setCount] = useState(0);
useEffect(() => console.log(count), [count]);
setCurrPos(preevCount => prevCount + 1);
I am quite new to Vue.js and while developing my first project i have stumbled upon a problem which I think is related to the component's lifecycle.
The context is the following:
I am using Vue 3 with composition API.
I have a "Map" component in which I use d3.js to show a chart.
In my Setup() method I have onBeforeMount() and onMounted().
In onBeforeMount() method, I want to use data from my Firestore database for the values in the chart. The console.log on line 47 shows the data correctly.
In onMounted(), is where I plan to put my d3 chart. But when I try to access the data as in console.log on line 55, I get undefined...
Ideally, from "Map" component, I want to fetch the data from my database and use it in order to create the chart and then have the component render the chart.
Then I would have another component called 'MapSettings" that will be able to alter the data in "Map" such as filters etc...and have the values automatically updated in the chart.
Finally, both components will be siblings and have same parent component. So "Map" and "MapSettings" are on same hierarchical level.
But first I need to understand why I am getting undefined.. Any help or suggestion would be greatly appreciated!
Your lifecycle hooks look nice. The problem that you're facing has to do with code been executed asynchronously and code been executed synchronously.
You're declaring a function that uses async-await feature. This function will be executed asynchronously. In this case, you're getting data from Firestore and storing it in a ref at onBeforeMount().
On the other hand, you're declaring a normal function at onMounted() trying to access a ref's value, which will result in undefined because the function that you define at onBeforeMount() didn't finish its execution (or it's in the event queue) when onMounted is called.
That's why you first see the console.log that comes from onMounted.
One solution would merge both functions in one lifecycle hooks and use async await:
setup() {
const {actorDocs, load} = getActorDocs()
const actorsData = red([])
// load actor data from db
onBeforeMount( async () => {
await load()
actorsData.value = actorDocs
console.log(actorsData.value)
// manipulate it here...
})
}
Keep in mind that you cannot pause with async-await a lifecycle hook. What you're pausing is the function that Vue will execute in that hook. Indeed, this is really nice because pausing a hook wouldn't be efficient at all.
i face that problem, in my case i want use imgsRef.value out of onBeforeMount scope. How to get imgsRef value out of beforeMount scope?
onBeforeMount( async () => {
await axios
.get("http://localhost:3000/ourMoment")
.then((response) => {
imgsRef.value = response.data
// imhsRef get the value from api
console.log(imgsRef.value.photo)
})
})
// i try to concole.log here but the value still empty
console.log(imgsRef.value)
I'm working on my first Vue 3 (and therefore vuex 4) app coming from a pretty solid Vue 2 background.
I have an component that is loading data via vuex actions, and then accessing the store via a returned value in setup()
setup() {
const store = useStore();
const fancy = computed(() => store.state.fancy);
return { fancy };
},
fancy here is a deeply nested object, which I think might be important.
I then want to run a function based on whenever than value changes, so I have set up a watch in my mounted() lifecycle hook
watch(
this.fancy,
(newValue) => {
for (const spreadsheet in newValue) {
console.log(Object.keys(newValue[spreadsheet].data))
setTimeout(()=>{
console.log(Object.keys(newValue[spreadsheet].data))
},500)
...
I tried using the new onMounted() hook in setup and watchEffect and store.watch instead, but I could not get watch/watchEffect to reliably trigger in the onMounted hook, and watchEffect never seemed to update based on my computed store value. If you have insight into this, that would be handy.
My real issue though is that my watcher gets called seemingly before the value is updated. For instance my code logs out [] for the first set of keys, and then a half second later a full array. If it was some kind of progressive filling in of the data, then I would have expected the watcher to be called again, with a new newValue. I have also tried. all the permutations of flush, deep, and immediate on my watcher to no avail. nextTick()s also did not work. I think this must be related to my lack of understanding in the new reactivity changes, but I'm unsure how to get around it and adding in a random delay in my app seems obviously wrong.
Thank you.
updated: function() {
console.log("updated");
this.$emit("render-vue", this.$el.offsetHeight);
},
This works fine enough...but in my app, props get updated (which I don't care about), and then there is a fetch() that updates data, resulting in additional DOM rendering.
So, that means that I get 2 'updated' events in succession! 👎🏾
Essentially, I only want updated to perform the $emit when data has been fully updated and the DOM is finished.
Currently, $emit is happening 2 times in succession, and that's not helping situation - IT DOM gets updated with props and then right after that another updated occurs when data gets updated after fetch().
Now, I could watch - tried that. The issue there is that $emit will fire off before all DOM is updated, sending the wrong info as argument.
It's almost like I need to watch a specific piece of data...and then, and only then, have updated send the $emit. 😖
For additional context, there are no children - this is a child component.
I can probably get this to work by using a setTimeout()...but come, on! That's sloppy! 👎🏾
In the code block that fetches the data, set a property to indicate new data is available
fetch(url)
.then(() => {
// whatever you're doing with the data
this.newData = true;
});
Check this state variable in the updated hook
updated() {
if (this.newData) {
this.$emit("render-vue", this.$el.offsetHeight);
this.newData = false;
}
}
I have a computed property - playerId that is referencing an external object that is not updating.
For example:
var player = require('players');
computed: {
playerId: function() {
return player.id
}
}
If I run this call in a click event it outputs the correct ID. However when this gets updated - computed on its own doesn't update. How do I get this to work? Or am I going about this incorrectly?
Computed Property in Vue.js does not get reactive with the data which doesn't have any reactive dependecy. For example, the code below would not be updated in each time, because Date.now() has no reactive dependency. The result of this computed value gets cached and it always returns the same value as the one returned at the first time.
computed: {
now: function () {
return Date.now()
}
}
Then, you probably would like to know how to make your external object reactive. The point is, you better put your object into data section in order to track the change of it with Vue's internal watcher. If your computed property has even one a reactive dependency such referencing data or calling method, it is notified every time the dependency get updated and the content returned from the computed property is going to be updated as well.
https://v2.vuejs.org/v2/guide/computed.html