React input onchange slow

At the release of React v One of the great additions to React v PureComponent class. In this post, we will look in depth at what React.

29 ReactJS basics Input OnChange Event

PureComponent and the goodies it brings us. Read on. Useful tip: Use Bit to encapsulate components with all their dependencies and setup. Build truly modular applications with better code reuse, simpler maintenance and less overhead. We used to write our components like this:. For change detection, React use a local state, which is only local to a component, when the state changes the component and its children are re-rendered to update the UI of the changed state.

Then we have the props which is a short form of properties for passing attributes to components, it is received in the constructor as this. If we enter 1, the count state is updated to 1, when we enterthe count state will be updated to When we enter a certain number and re-enter the same number again.

Should the DOM of the component re-rendered? No, of course not, that will lead to slowdowns in our apps. But here in our component, the component will be re-rendered even if the previous state and the current state is the same value.

To visualize this re-renders with React Devs Tools. Open your DevsTools and click on the React tab. If the HighLight Updates check-box is not available, click on the Settings box on the right side, a popup will appear, then click on HighLight Updates.

If we now interact with our app, we will see color highlights momentarily appear around any components that render or re-render. Considering the component above, if we click the input and type in 1 the component will re-render to reflect the value 1 on the DOM. We will see the borders around the Count component flash color blue in my machine. Now, if we type 2 there will be a flash, then we type 2 again.

We know this is a small app and we can do with the re-renderings, but imagine a complex app with thousands of re-renders imagine how sluggish your app will look, you see the slowdowns will become noticeable. We can throw a little salt in our app to boost its performance by adding the lifecycle method, shouldComponentUpdate. This method tells React whether to update a component or not, if it is to update a component it returns true, if not it returns false.

The basic skeleton of the function, it takes the next props values in the nextProps parameter and the value of the next state in the nextState parameter.HTML form elements work a little bit differently from other DOM elements in React, because form elements naturally keep some internal state.

For example, this form in plain HTML accepts a single name:. This form has the default HTML form behavior of browsing to a new page when the user submits the form. If you want this behavior in React, it just works.

In React, mutable state is typically kept in the state property of components, and only updated with setState. Then the React component that renders a form also controls what happens in that form on subsequent user input.

For example, if we want to make the previous example log the name when it is submitted, we can write the form as a controlled component:. Try it on CodePen. Since the value attribute is set on our form element, the displayed value will always be this. Since handleChange runs on every keystroke to update the React state, the displayed value will update as the user types.

While this means you have to type a bit more code, you can now pass the value to other UI elements too, or reset it from other event handlers. Notice that this. For example, this HTML creates a drop-down list of flavors:. Note that the Coconut option is initially selected, because of the selected attribute. React, instead of using this selected attribute, uses a value attribute on the root select tag. This is more convenient in a controlled component because you only need to update it in one place.

For example:. You can pass an array into the value attribute, allowing you to select multiple options in a select tag:. Because its value is read-only, it is an uncontrolled component in React. It is discussed together with other uncontrolled components later in the documentation. When you need to handle multiple controlled input elements, you can add a name attribute to each element and let the handler function choose what to do based on the value of event.

Note how we used the ES6 computed property name syntax to update the state key corresponding to the given input name:.

Also, since setState automatically merges a partial state into the current statewe only needed to call it with the changed parts. Specifying the value prop on a controlled component prevents the user from changing the input unless you desire so. The following code demonstrates this. The input is locked at first but becomes editable after a short delay. It can sometimes be tedious to use controlled components, because you need to write an event handler for every way your data can change and pipe all of the input state through a React component.

This can become particularly annoying when you are converting a preexisting codebase to React, or integrating a React application with a non-React library. In these situations, you might want to check out uncontrolled componentsan alternative technique for implementing input forms. Is this page useful? Edit this page. Main Concepts.

Advanced Guides. API Reference. Concurrent Mode Experimental. Previous article. Lifting State Up.The onChange event in React detects when the value of an input element changes.

Event handlers are an important part of React. Learn more about another event handler, the onClick event handler. The above code displays a single input field which, when typed in, passes its current value to the handleChange function. Therefore, to log the name of the input field, we can log e. Log the whole event object to the console and click through it to see what other useful information it provides. The example above was of a functional component.

This is extremely useful for keeping track of the current input fields values, and displaying them on the UI. Your email address will not be published. Don't miss the latest React tutorials. No spam, ever. Opt out at any time. If you'd like to receive a friendly email once in a while of all new React tutorials, just pop your email above! I appreciate the support! Email address We will never share your email with anyone else. Comments Liron Atar says:. March 2, at pm. James King says:. March 11, at pm.

Anonymous says:. April 6, at am. May 19, at pm.Dump it in a dropdown, and you overwhelm your users. How many even know vanilla dropdowns support search? And besides, you can't style those. Your designer will throw a shit fit. Default browser crap in his beautiful design?

No, no, that won't do. Looks vanilla, works vanilla. First open is slow, but search is fast if you know it exists. If you don't, you're screwed. You could give users an input field and validate against the list of possible entries… no way that's going to be a nightmare, eh? Is it stanfordStanfordstanford universityStanford universityor Stanford University?

Some people will enter stnraofd. No, no, the answer is both. You need an input field and a dropdown. Input filters dropdown, dropdown guides users. Jed Watson's react-select library gives you input fields with dropdowns. Users can use the input field or use the dropdown. We changed the import Select from to use react-virtualized-select and… that's all. It opens quickly, and I was typing that whole time that nothing was happening. Browser's UI thread still blocking. Brian Vaughn's react-select-fast-filter-options is practically too long to mention in a tweet, and it solves the second problem: fast search.

It builds an index of your options and uses advanced computer sciencey algorithms discovered some time in the 60's, probably. We rarely have enough data to worry about actual computer science on the front end, but sometimes we do.

After that you'll get thoughtfully written emails every week about ReactJavaScriptand your career. Lessons learned over my 20 years in the industry working with companies ranging from tiny startups to Fortune5 behemoths.

And wow always take away lessons with me. And very relatable. Join over 10, engineers just like you already improving their careers with my letters, workshops, courses, and talks. Have a burning question that you think I can answer? I don't have all of the answers, but I have some!GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community. Already on GitHub?

Sign in to your account. Formik library have built-in tools to avoid rerendering all form fields, after changing one of this fields? I'm having the same issue. Typing inside a field is very slow in a form that contains 10 fields, even more with React Native when you create a custom field component with several children components and it internally uses the setFieldValue on a TextInput. This is because every time that a key is entered all the children components of the Formik component are re-rendered.

Is there any way to avoid this? The way I've gotten around it is making a form field component that tracks its own value state setting only its own state onChangethen calls Formik's setFieldValue onBlur, instead of onChange. Then the re-render on a keystroke is contained to that field component rather than the whole form, while the value change is propagated to the rest of the form when the field loses focus. I'm running into this issue myself using a bunch of custom components and lots of React-Selects.

In particular the the repainting of the react-select elements is obnoxious because the little X and Toggle chevrons blink on every repaint. I also have performance issues, when using yup validations when I try to type really fast. Any chance to add a debounce on the handleChange function?

I'm experiencing this issue as well with 1. I was migrating away from mobx-react-form because I liked the render props of Formik but this re-render performance is definitely an issue. It's not an issue with mobx-react-form probably because MobX updates are so optimized.

Have the same issue with Field as well as Fastfield even with the latest version. My form has some 30 fields Text inputs, Selects and radiogroup and there is a serious lag for each keystroke. Upgrading formik didn't make any difference. Is there a way to use debounce with formik? It's very needed feature I have the same issue, tried memoizing the error object but Formik seems to update the error on all fields. Unsurprisingly, it is significantly faster with prod build but even then UX is annoying for mid or big size forms.

For these reasons, maybe we could be given the ability to provide our own function to override some or all of the functionality of runValidations? Essentially we just need some sort of hook that gives us the ability to avoid the internal setState calls if we need to. The alternative is for us to do the errors comparison in shouldComponentUpdate on our rendered component, but if the error objects match you still also have to compare all the other props - the mechanism doesn't really sit at the right level, it's acting too late.

State Colocation will make your React app faster

Anyway, just trying to throw some thoughts out there. The other thing that could be done, of course, is just to have synchronous validation, which I know has been considered. But that isn't exactly ideal either, because it would be render-blocking. Maybe we just need to wait for Suspense Any progress on this?Watch "Lifting and colocating React State" on egghead. One of the leading causes to slow React applications is global state, especially the rapidly changing variety.

Allow me to illustrate my point with a super contrived example, then I'll give you a slightly more realistic example so you can determine how it can be more practically applicable in your own app.

Play around that for a second and you'll notice a significant performance problem when you interact with either field. There are various things that we can do to improve the performance of both the DogName and SlowComponent components on their own. We could pull out the rendering bailout escape hatches like React. But I'd like to propose an alternative solution. If you haven't already read Colocationthen I suggest you give that a read.

Knowing that colocation can improve the maintenance of our application, let's try colocating some state. Observe that the time state is used by every component in the App, which is why it was lifted to the App. However the dog state is only used by one component, so let's move that state to be colocated updated lines are highlighted :.

Typing in the dog name input is WAY better now. And what's more, the component's easier to maintain thanks to colocation. But how did it get faster? I've heard it said that the best way to make something fast is to do less stuff. That's exactly what's going on here. When we manage the state higher up in the React component tree, every update to that state results in an invalidation of the entire React tree.

React doesn't know what's changed, so it has to go and check all the components to determine whether they need DOM updates. That process is not free especially when you have arbitrarily slow components. But if you move your state further down the React tree as we did with the dog state and the DogName component, then React has less to check.

It doesn't even bother calling our SlowComponent because it knows that there's no way that could have changed output because it can't reference the changed state anyway. In short, before, when we changed the dog name, every component had to be checked for changes re-rendered. After, only the DogName component needed to be checked. This resulted in a big performance win! Where I see this principle apply in real-world applications is when people put things into a global Redux store or in a global context that don't really need to be global.

Inputs like the DogName in the example above are often the places where this perf issue manifests itself, but I've also seen it happen plenty on mouse interactions as well like showing a tooltip over a graph or table of data. Often the solution that people try for this kind of problem is to "debounce" the user interaction ie wait for the user to stop typing before applying the state update. This is sometimes the best we can do, but it definitely leads to a sub-optimal user experience React's upcoming concurrent mode should make this less necessary in the future.

Watch this demo from Dan about it. Another solution people try is to apply one of React's rendering bailout escape hatches like React. This works pretty well in our contrived example because it allows React to skip re-rendering our SlowComponentbut in a more practical scenario, you often suffer from "death by a thousand cuts" which means that there's not really a single place that's slow, so you wind up applying React.

And when you do that, you have to start using useMemo and useCallback everywhere as well otherwise you undo all the work you put into React. Each of these optimizations together may solve the problem, but it drastically increases the complexity of your application's code and it actually is less effective at solving the problem than colocating state because React does still need to run through every component from the top to determine whether it should re-render.By using our site, you acknowledge that you have read and understand our Cookie PolicyPrivacy Policyand our Terms of Service.

Stack Overflow for Teams is a private, secure spot for you and your coworkers to find and share information. I have a form with multiple text inputs. I have them all set up as controlled inputs.

When typing, there is a lag of up to several seconds for the new text to display in the field. Here is an example field:. I had a similar situation and my solution was to disable React Dev Tools. They were affecting input fields somehow.

The problem is it's not enough to refresh a page if you have clicked React Dev Tools tab. They are still affecting your inputs. You have to open new page to stop them. You can also remove them from Chrome completely but I don't recommend doing this 'cause they are useful. There are many possible reasons for this to happen. I faced the similar issue and filtered the main cause to:.

Whatever may be the reason, I found a quick fix for this. If you just want to store it to the state but not using it for live rendering.

Managing state and controlled form fields with React

Then you can safely replace the 'onChange' to 'onBlur'. This has no dealay and lag. If you know any other case where this will not work, do let me know! Here is an example for an input pattern, Plug in or pattern for dealing with large forms in React? The main thing is to have your input as a component that passes changes to the parent but doesn't update from the props if they are the same. My problem was that my state object was complex and thus causing rendering issues.

My solution was to manage the state of the notes in my component, then on blur update the container state. Seeing as this still gets responses, thought I'd update this and close it.


comments

Leave a Reply

Your email address will not be published. Required fields are marked *

1 2