-
Notifications
You must be signed in to change notification settings - Fork 13.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bug: changing value of component in ionChange results in an infinite loop #20106
Comments
ionChange is triggered with every change of the input value, either through user input or programmatically. If you want your handler to be triggered only when the user changes the input, you should use ionInput event instead. |
@masimplo Thanks for that clarification; I now see what happened. The event types for onIonInput may be broken. I tried using |
And as a followup, it seems that other inputs don't have onIonInput or anything like it that only triggers for inputs via that element. For example, IonDateTime and IonToggle only have onIonChange. What are we supposed to do in those cases? |
Hi, I have the same problem, this is my organization :
I have 2 forms that use a single state and when I change a value of a field from one form, it trigger the update method on both forms. (this is a problem because I fetch data on each update) How can I trigger only one time the update method ? |
My first example is not really explicit because I can use differents filters on differents pages but I have another example where I haven't found a solution :
At the end of the form I want to reset it, but if I do it it just reset some fields because they all interacts with the same object and re-trigger the update method for each input... The only workaround I have is to use one state for each input and when reset the form, call the setter of each state 😞 EDIT: Example:
becomes:
|
@ebk46, Hi Evan. It seems there is not any good document or sample code for Ionic-React. Can you guide me, please? |
Same problem exist about onIonInput event |
Any ideas how to deal with that? I have IonSelect that is wired with redux state and when logic other than user interacting with that component is updating the values the ionOnChange event is triggered. How to know where the change is coming from? |
|
This is quite an annoying "feature". Additionally, My current workaround is to keep a |
Note that this feature ruins use-cases where one input field depends on another input field. You can end up in a weird update loop and the end state becomes completely unpredictable. |
There is no |
It actually works when using useEffect as below:
The problem is, that when checking for state-changes right after setFoo(newValue), the state didn't actually change yet. useEffect() can be triggered, when a state changes ... so, all you have to do is tell useEffect() in an array, which changes it should listen to. Hope this helps. |
This affects most components that have I had filed #22365, but then realized this issue already existed. Here is a copy of my bug report with an up to date reproduction: Bug ReportIonic version: [ ] 4.x Current behavior: Expected behavior: I would expect programatically changing the value in the ionChange callback would not trigger another ionChange, similar to how the native checkbox element works. Steps to reproduce:
Other information: Changing this behavior is likely a breaking change. |
What about leave ionChange as it is, for backward compactibility. And provide new event 'change' or something similar with fixed behaviour? Next step: Events like @change in vuejs can be linked to this new fixed event, but when somebody uses @ionChange, they will be facing same issue till next release of Ionic v6, as mentioned bellow. Next step: In v6 version this names can be replaced, for smoother transition... Because it looks, this won't be fixed in short future. |
I still cannot find a workaround for this at the moment.. |
A bug-around for anybody trapping into this Issue:
|
My workaround consists to check if the select has the focus : let hasFocus = false;
<IonSelect value={value} onFocus={() => hasFocus = !hasFocus} onIonChange={e => hasFocus && onChange(e.detail.value)}>
...
</IonSelect> |
Is there any update on this? |
I am an Angular guy, I don't know if it will help in react components but you can check this I have found a workaround. ion-toggle unnecessarily triggers change event when default value is true |
UPDATE 12/20: The "key" workaround is not fully working after all. If you make a selection and hit OK all is well. If however you open the select and hit OK without making a change (so it's the same selection) the infinite loop still happens. Just want to mention that I also ran into this infinite loop using an I experience it when select options are simple strings and For anyone else using RHF alongside Ionic, I went with a variation on @Najros "bug-around". Thanks for that! <Controller
name="saleGroups"
control={control}
render={({ field: { value, onChange } }) => (
<IonSelect
key={value.toString()} // required to prevent infinite loop for "multiple"
multiple
value={value}
onIonChange={(e) => onChange(e.detail.value)}
>
{selectOptions.map((item) => (
<IonSelectOption
key={item.id}
value={item.id}
>
{item.name}
</IonSelectOption>
))}
</IonSelect>
)}
/> I did manage to get it working with the more complex object value select. It's a bit more complicated as it involves the I'll update with any changes after upgrading to Ionic v6 |
Facing the same loop issue in combination with React Hook Form (Controller) using Ionic v6. Edit: Workaround with mentioned
That's working for me even when I update with no value changed. |
well,i tried the workaround above such as hasFous & key , but this doesn't work. When i add random key on IonToggle,it works and won't trigger more or infinite loop of onIonChange. |
Hi. I'm still running into these infinite loops with React Hook Form and so far none of the above workarounds do the trick. What I have so far found to work is to only call <Controller
name="multiSelectExample"
control={control}
render={({ field: { value, onChange } }) => {
return (
<IonSelect
key={value.toString()}
multiple
value={value}
onIonChange={(e: CustomEvent<SelectChangeEventDetail<Array<string>>>) => {
// EARLY RETURN IF VALUE WASN'T CHANGED
if (
JSON.stringify(e.detail.value) === JSON.stringify(value)
) {
return
}
onChange(e.detail.value)
}}>
{selectOptions.map((option) => (
<IonSelectOption
key={option.value}
value={option.value}
>
{option.label}
</IonSelectOption>
))}
</IonSelect>
)
}}
/> While the above is a React Hook Form sample, the issue doesn't seem to be limited to the React Hook Form integration. #24691 points back to the original RHF issue which has a non-RHF repro - https://codesandbox.io/s/thirsty-pasteur-wqpuz?file=/src/App.tsx:137-143 Hope all this extra info and another workaround is helpful! |
Hello everyone, I've created an RFC to discuss changes to the API design that should correct this issue: #25532 Please share your thoughts and if there is anything we may be missing. Thanks! |
I also commented on #24584 - try an earlier version of react-hook-form version if you need a workaround for now. 7.12.2 worked for me. |
This issue has been resolved in this pull request: #25858 and will be available in the next major release (v7) of Ionic. |
Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Ionic, please create a new issue and ensure the template is fully filled out. |
Bug Report
Ionic version:
[x] 4.7.11
Current behavior:
When the value of an Ionic input element is changed from OUTSIDE of the element, the element's onIonChange is triggered, thereby duplicating the change event.
Expected behavior:
As with every other React input, the onIonChange should only be triggered when the value was change from the element itself.
Steps to reproduce:
See console in included stackblitz.
Related code:
https://stackblitz.com/edit/ionic-v4-11-7-controlled-inputs
Other information:
This same bug is happening with other Ionic inputs as well. I haven't tested all of them, but it is happening with at least IonToggle and IonDateTime.
This is bad because unless each input has its own separate controlled state, doing something like clearing a state object could trigger 10+ onIonChange events, leading to race conditions and other annoyances.
Ionic info:
The text was updated successfully, but these errors were encountered: