Why result of state update is reacting in 2 different ways - javascript

I have created a simple TicTacToe using react-hooks.
Sometimes I am getting result before my state update is shown on screen.
Sometimes it is showing result after update is shown on screen.
I am not getting why it is reacting in 2 different ways.
Please find the code link below.
playground link

alert() function is blocking function so when alert window opens your app is on pause until user hit ok button.
alert function can sometimes race with rendering, that's why sometimes the alert shows before the last render and your app on pause so you will not see the change on the grid.
it happens when you
The solution is to replace alert() whith another visual element such as modals

Issue probably comes from your useState, you can try adding dependency array for the useState with player change so it only checks the game after each round.
From:
useEffect(() => {
CheckGame();
});
To:
useEffect(() => {
CheckGame();
}, [player]);

Related

AntD React InputNumber Increase/Decrease buttons appear to start infinite loop

I am experiencing some unusual behaviour with AntD InputNumber component, specifically using the up/down incrementation buttons:
I have a very basic implementation of the component as follows:
<InputNumber min={1} max={10} defaultValue={3} onChange={changeWeight} />
calling function:
function changeWeight(weight) {
console.log(weight);
}
On the face of it, it all seems to work fine, as I click on the increment button, I see the result in my console for each click. 3 clicks up and my console reads:
Great! However, if I then place a debugger inside the called function like so:
function changeWeight(weight) {
debugger;
console.log(weight);
}
then refresh the screen and hit the increment button once, I hit my breakpoint, console is logged, I hit continue then instead of the process finishing, it goes straight back to the breakpoint again. The function is called again and again infinitely it seems. I have found if you put a max value on the InputNumber component it does stop at that number. The below console log is from hitting the button just once, but the breakpoint being hit many times...
Again, if I remove the debugger breakpoint, all seems normal and the console logs just the once when the button is clicked.
Also, if I type numbers into the component it only hits the debugger breakpoint once. Just these buttons seem to be causing a problem.
Has anyone else experienced this or have any ideas as to what may be causing it? I am very confused.

framer-motion - dom node does not unmounts immediately after exit animation

I have created an animated modal container
it's working fine for the most part
the only issue is after doing the exit animation it takes a second or two to unmount (in that period cannot click anywhere else)
code sandbox - https://codesandbox.io/s/restless-platform-oovo1?file=/src/App.js
To see the issue 👇🏻
click show modal button
Click anywhere to close the modal
notice that the scrollbar still exist denoting modal is not unmounted
Also, you cannot reopen modal immediately on clicking of the open modal button after exit animation (for that 1 sec)
I had seen safeToremove but didn't understand how to use it as there is no proper documentation
I agree that the documentation is a little frustrating where this is concerned - here's what I've learned through playing around with it.
The documentation shows the code for usePresence() within the presence component to be:
import { usePresence } from "framer-motion"
export const Component = () => {
const [isPresent, safeToRemove] = usePresence()
useEffect(() => {
!isPresent && setTimeout(safeToRemove, 1000)
}, [isPresent])
return <div />
}
This initially seemed arbitrary/purely an example. However, after playing around with it, it turns out that if you initialize usePresence(), this useEffect code is now necessary for the presence to work correctly and in part determining the functionality of the presence. Try initializing usePresence and then commenting out the line
// !isPresent && setTimeout(safeToRemove, 1000)
It will break your animate presence.
So the setTimeout function wrapping safeToRemove is, in fact, determining core functionality of the AnimatePresence and able to determine the timing of the virtual DOM becoming clickable again, etc.
Now, I was playing around with the crossfade AnimateSharedLayout, so it was a little weird to be messing with the safeToRemove timing when I wasn't determining the animations themselves, but if you are setting up the animations for the modal yourself, I think that if you sync the time in that setTimeout function with the length of your animations, it should solve your problem.
I'm still trying to figure out exactly how all this works, so comment back and let me know what you find and we'll be one step closer to mastering using Framer v2's newest tools.

Infinite loop when overriding graphHandlerMouseUp on MxGraph using Angular

I have a difficult question to explain and I'm way out of my comfort zone as far as expertise in Javascript, TrueType, Angular and MxGraph are concerned... Hope to be able to explain.
I have an Angular component displaying and MxGraph. I was able to integrate MxGraph with Angular following this link (How to integrate mxGraph with Angular 4?). Even if I use Angular 7, the solution still works...
The graph is displayed correctly on the page and everything works fine, including my override of the function graphHandlerMouseUp, which I do with this code:
// Save the position of the mouse when releasing the button: used for
// detecting the target in a drag and drop
mx.graphHandlerMouseUp = mx.mxGraphHandler.prototype.mouseUp;
mx.mxGraphHandler.prototype.mouseUp = function( graph, evt ) {
currentdropX = evt.graphX;
currentdropY = evt.graphY;
mx.graphHandlerMouseUp.apply(this, arguments);
}
When I run this page for the first time, no problem happens.
Then through a button I call a page with another component (through routing). If from this page I go back to the first component (again through a routerlink) the page and the component with the MxGraph loads correctly, BUT when I use this function (i.e., release the mouse button).
It seems to me a recoursive problem, as when I put a console output like this:
// Save the position of the mouse when releasing the button: used for
// detecting the target in a drag and drop
mx.graphHandlerMouseUp = mx.mxGraphHandler.prototype.mouseUp;
mx.mxGraphHandler.prototype.mouseUp = function( graph, evt ) {
currentdropX = evt.graphX;
currentdropY = evt.graphY;
// INIFINTE LOOP HERE
console.log("Test");
mx.graphHandlerMouseUp.apply(this, arguments);
}
The "Test" is written a number of times which is continuously growing. Yet, if I understood, this was the correct way of overriding the function. Of course on the first load of the page, "Test" is displayed once. Passing to another component and then back on this it is displayed an "infinite" number of times (until I reach the: "ERROR RangeError: Maximum call stack size exceeded")...
I tried also to remove that override, and besides the obvious lack of the functionality, the very same problem happened to the function "mxDragSource", which is overridden with the same approach.
As I said: I'm not expert enough in javascript, truetype, MxGraph or Angular, so any hint, even if obvious, is very welcome!
Thanks!
The first time you run your code, you store mx library's mouseUp event in a variable and you assign a new function to mouseUp event in which you call the old mouseUpEvent.
The second time you run your code, you store your current mouseUp event (that you have modified) and you assign a function in which you call the old mouseUpEvent, which is the same you stored previously. There goes your recursion !
What you need to do is override the third-party function properly, so you don't execute your code twice.
How to do it ?
You can create a mixin and use this mixin in your componentB/ If you have no idea what is it and how to do it, please reproduce your problem in a stackblitz I'll be glad to help you to implement it.

change bootstrap button text before rendering d3 svg object

I've got code aimed at visualizing some complex data. The user first selects a data file to load; after clicking the load button, the page generates a "plot" button with an onclick event handler with the function renderPlots().
When the user clicks the "plot" button, then all the plots are properly generated and I'm happy. However, in the case of a larger data set, the plotting process may take a few seconds so I'd like to change the button text to something like "rendering..." while the plots are being generated so that the user knows their plots are on the way.
As per the bootstrap documentation for dynamically changing button text, I've tried something like
function renderPlots() {
$("#render").button("loading");
rest of code that does all the D3 plot generating...;
$("#render").button("reset");
}
The problem with the above code is that it doesn't actually change the button text first, it's doing things asynchronously and I'm at a loss of how I can force the button text to change on screen before any plotting actually starts.
Any thoughts?
Actually, if I understood the issue, stuff is running synchronously — not asynchronously — which is why the browser doesn't get a chance to refresh the DOM with the new button text prior to starting the big processing task. If you were to console.log the button text somewhere between the two calls to .button() you'd see that the text is set to "loading"; it just doesn't appear yet.
If so, then using setTimeout to delay the start of processing until the next "frame" will fix the issue:
function renderPlots() {
$("#render").button("loading");
setTimeout(function() {
// rest of code that does all the D3 plot generating...;
$("#render").button("reset");
}, 100); // even 0 will do the trick
}

javascript property race condition

I have a phonegap project on iPhone and Android. The issue appears to be a race condition on the surface, but I don't understand how it happens. Users are able to click on a button which has a closure callback that sets a property of an object, and then clears the screen and loads the main menu. In code:
button.onclick = function (employee) {
return function () {
employee.task = "some task";
returnToMenu();
}
}(employees[i]);
After the user is back on the main menu, they can click on a button that loads a screen which displays all the users. If an employee has that task property set, additionally formatting should be done to the button for that employee.
if (employee.task)
// style the button being created for this employee
Somehow, if one clicks fast enough, the formatting is not done. If you click back (to the main menu), and reload the screen, the formatting is now done. Given the code above, I do not see how employee.task could possibly return undefined after the menu has been loaded. What's going on here?

Categories

Resources