I have a component that uses onClick and onFocus. Both of the events call the same function that loads data from an API.
When the user is tabbing through elements on the page and lands upon this component's child textarea, onFocus runs and loads data from an API.
However, when the user clicks on the component's textarea child, both the onClick and onFocus events try and load data from the API. I want to prevent both events from firing a function twice.
I do NOT want to put events on the text area itself if possible.
function DataRow(props) {
function focused(e){
props.loadDataFromAPI(); /* This will get ran twice if clicked on tr element's textarea */
}
return <tr onFocus={focused} onClick={focused} ><textarea></textarea></tr>;
}
As you can see, I want it to get called when the user clicks on the tr as well as clicks/focuses on the textarea. I just don't want that duplicate call when clicking on the textarea!
Maybe you can implement a debounce system to avoid this behaviour.
In this way not only you will avoid this double event firing, but you will prevent user to spam you and polling request if he starts to repeatedly click on the button.
There are a lot of answers out there about debouncing, maybe you can give a look at lodash debounce, or google for specific React systems like debounce hooks.
Related
I have a component that dynamically builds check boxes, from the result of an API call.
I am selecting the first radio button in a group, as a default, when the component is created.
Based on what radio button is checked/selected the page displays differently. So the radio button is selected after the page loads, but the onChange function does not get fired to display the page correctly. I am looking for a way to fire the onChange event after loading, API fetch, and displaying the radio buttons.
Thanks you helped me figure it out. In the final line of my useEffect hook, I click the first radio button in the group. That both sets the default and fires the change event. I tried setting it to check but that did not fire the change event.
useEffect(() => {
.
.
document.getElementsByName('rbImageGroup')[1].click();
}, []);
I want to simulate the progressive bar that is on Snapchat story when recording a story. Everything is done but the button touch effect. How do you call a function while holding the button, not just onPress?
If you are using one of the Touchable buttons, I would use a combination of the onPressIn and onPressOut props to perform an operation while the user is holding the button. See more info here
I have made a navbar, which holds a searchbar, and 3 icons.
On clicking these icons, a modal is rendered.
I wanted help with two things.
Closing the modals on outside clicks!, and
The hover element is slow because it has three states, every time it is called it re-renders the code from bottom to top. I wanted the hover to have one state assigned to one parent element. But on doing that, the hover effect for all three buttons gets activated at the same time.
Code is up on : https://codesandbox.io/s/unruffled-snowflake-he95w
Please feel free to edit the code and pass me the edited fork.
I have tried handleBlur, passing an event, and eventListener.
https://codesandbox.io/s/unruffled-snowflake-he95w
Expected - Modal rendered on screen should get disappeared on clicking outside the modal.
P.S - semantic UI icons are not rendering, but they are there. They will activate if you hover over them.
Credits - SVG close icon problem solved by Drew Reese.
Ah, I see. Your ToolBar is the controlling component, i.e. the state about whether or not each toolbar item is open is stored there. You need to pass a close handler to the children components so when a "close" button is clicked it is calling the callback the parent passed in.
Here is a fork of your sandbox where I pass in an onCloseClick callback to the calendar/picker thing that simply toggles that state value back to false to close it. The picker then just assigns that callback as its onClick handler for the contaning for the close button.
You can apply the same logic to the other two components.
Note: since the icons aren't rendering for me either I added some text to the buttons so they are easier to find/see.
I have a very simple code snipper in my page where I have a span. Hovering over this span displays a popover for which I am using angular-ui-bootstrap.
<span uib-popover="This is a popover from Akhilesh"
ng-mouseenter="vm.logToConsole('I am trying hard...')"
popover-trigger="mouseenter">Hover over me to see a popup..!!</span>
Basically I have written a function which makes and API call when the user hovers over this span. The problem here is that let's say I have 10 span tags one below the other and the user quickly moves from 1st span to 10th span (in the process hovering over all 8 spans in between), the API call will get triggered for all the spans. This is what I do not intend to have.
Any idea how can I implement the debounce functionality here?
Use a delay, like one second, after the mouse enters the region, then if the mouse hasn't entered another area, make the API call.
The popover-is-open attribute was added under the 0.13.4 release that can be used to watch the state of your popover like so:
<span uib-popover="This is a popover from Akhilesh"
popover-is-open="vm.isOpen"
popover-trigger="mouseenter">Hover over me to see a popup..!!</span>
Then in your controller:
$scope.$watch('isOpen', function() { });
But if you are just trying to keep the popovers from opening so quickly, consider using the popover-open-delay attribute.
Depending on your use, I found the best method is to simply add ng-mouseover, ng-click etc to the element and define a function to be called.
You can even create a variable and attach it to that objects scope on the fly to keep track of the state (open close).
Kind of hacky, but there is currently no way to define a function that is called on open and on close within ui-bootstrap popover.
I have a navigation view with one button in the toolbar. Based on the view pushed, the button's label and functionality should chang. I've managed to do this by creating many buttons and activating them as needed (hide/show)
Instead of doing that approach I'd like to have just one button and in the controller change the text and action. Something along these lines:
this.getButton().setHtml("new text");
this.getButton().action = "newaction";
setHtml works, but setting the action doesn't. Examining the button in the console, I see the action changes but when I click it, it responds to the previous action.
Any suggestions on how to approach this?
Thanks
You should use setText instead of setHtml that, err... Doesn't seem to exist! And setHandler to change the handler function.
Alternatively, since you say that you're working in a controller, you can attach a function to the click event of the button and, inside this listener function, decide what action to execute in the current context.