Cursor jumping on controlled input

Hi,

I’ve come across what might be a bug, but I wanted to see if anyone else has come across it. It seems like a generic React issue, but I can’t replicate on a “vanilla”-React set up and it only happens when using Frontity.

The bug is that when entering a value in a controlled input, the cursor jumps to the end of the input.

Here’s the minimal code in index.js:

import React from 'react';

const Theme = () => {
  const [email, setEmail] = React.useState("");

  return (
    <div>
      <p><input value={email} onChange={(e) => setEmail(e.target.value) }/></p>
    </div>
  );
};

export default Theme;

and here’s it working correctly, without frontity: https://codepen.io/stephenharris/pen/JjjpdMj

Is anyone else able to replicate this issue? Have I done something wrong?

Thank you for any help you can provide!

Hi, I’m not sure what can cause this, but maybe the React component is being re rendered or updated unnecessarily?

Is the code you posted exactly as you have it in your project? I mean that maybe you have the component wrapped in a connect function to pass the state? That could be interfering somehow.

If so, you might be able to replicate the behavior using the @frontity/connect package in your codepen and see if the bug appears.

Thanks @orballo

The connect thing was what came to my mind too, but removing it doesn’t resolve the bug.

I’ve created a codepen replicating this issue: https://codesandbox.io/s/github/stephenharris/frontity-poc/tree/withoutconnect/?fontsize=14 and the code is here: https://github.com/stephenharris/frontity-poc/tree/withoutconnect

I had wondered if it was do with my dev environment, but even deploying it on now shows this bug (https://node-nsva8oqay.now.sh/).

Has anyone else come across this?

I was able to reproduce the problem. It is a bug, for sure, and I have opened an issue to fix it.

Thanks for reportint it! :blush:

By the way, while we work on the issue, if you need it you could try to use Uncontrolled components to create your form, it seems to work this way.

The problem is in the code of react-easy-state, a library we forked to create our state manager. More info about this problem on this issue of the original repo.

I was waiting for the answer of the creator of that library about the best way to fix this, although I already proposed a solution.

I have updated our own issue with that info.

Still no news from the library developer. If you guys still need this, please say it here and I’ll add the fix to Frontity.

Any update on this issue. We recently found this issue on the as well. Can you help add a fix for this?

There is a fix for this, I thought it was posted here somewhere on the forums, but I can’t seem to find it back. Maybe @luisherranz remembers it where it was posted, as I fixed it based on a solution he provided (or at least that’s how I remember it :sweat_smile:)

Solution
First, you should take a look on how to apply patches in node_modules. For this, we’ve use patch-package: patch-package

Then, you should take a look in the following file: /node_modules/@frontity/connect/src/scheduler.js
In there you should find the following code:

if (globalObj.EventTarget) {
  batchMethodsCallbacks(EventTarget.prototype, [
    "addEventListener",
    "removeEventListener",
  ]);
}

Put that block in a comment (or remove it) and apply the patch as described in the documentation of patch-package.

The problem should then be resolved.

PS: I’m not sure if this was already fixed in the latest version of Frontity. If that’s the case, then it could be that this solution isn’t relevant anymore, but it can’t hurt to try it out :slightly_smiling_face:

1 Like

Thanks for the help! It works!
I noticed that it can also be solved by upgrading frontity/connect to 1.3.0 to solve the problem as well.

But I noticed that after upgrading to frontity/connect 1.3.0, the state proxy include the construct handler, and it resulted in some issues on my project, when I use Arrays.map function on items the state.

For example, previously, after Arrays.map, the result is a pure object.

However, after updating @frontity/connect, the result becomes a proxy.

If I change anything on the result, it somehow changes the state and cause the re-render. Also it cause some memory leaking issue.
Do you have any suggestions on the usage of Arrays.map on the state items?

For more info on Proxies, you should take a look at this (if you haven’t already): Proxy - Javascript | MDN. For example, you could use proxies to log every change to the console, everytime you change a property of the target object.

Now, what you are doing is running the map-function directly on the state itself. This means that you are changing something on every item in the array, which causes the application to re-render on every change. This is the same as mutating your state, something which you shouldn’t do.

What you should do however, is making a copy of your current state into a variable e.g.

const langs = [...frontity.state.theme.langs];

Then use that copy to perform the update e.g.

langs.map((lang) => "test" + lang);

Then you can use that list to update your state (through the use of an action or however you prefer to do it) and trigger only one re-render of the application.

Hope that helps :slight_smile: