Why I avoid react's uncontrolled inputs

Поделиться
HTML-код
  • Опубликовано: 2 дек 2024

Комментарии • 96

  • @he-man5102
    @he-man5102 2 года назад +47

    You are 100% correct. I've had this conversation many times. It's annoying. It's like watching developers implement Redux to manage a couple of bits of state.

    • @adityatripathi1904
      @adityatripathi1904 2 года назад +4

      Haha this needs a thousand likes. People who use redux are wanna be developers.

    • @darelbvcr687
      @darelbvcr687 Год назад

      @@adityatripathi1904 redux is for losers lol

    • @Ndzzle
      @Ndzzle Год назад +1

      I like Formik.

  • @JerrenT
    @JerrenT 2 года назад +25

    These videos where you give common use cases for all of these problems are insanely valuable and make it much easier to understand. Keep it up man.

  • @smithastley1616
    @smithastley1616 2 года назад +13

    One of the most important lessons is don't prematurely optimise your code. This relates both to performance and over-generalising code for the future

    • @jollyjoker6340
      @jollyjoker6340 2 года назад +1

      Bingo. Stack Overflow is full of "how do I do this in Javascript?" questions with oldschool for loops as answers along with someone looping 100 million times to test the speed of the alternatives. The shortest and easiest to read version is always the correct one, even if you may have to optimize for speed later.

  • @anasouardini
    @anasouardini 2 года назад +2

    the only time I've used the uncontrolled way, is when I implemented monaco editor as a field in my form. and they have this method called `onMount()`. where it gives you a function which you'd use to get the value of the editor whenever you think it's time normally before the form is being submitted.
    so most of the time as the guy who wrote the docs said... your form is just fine with the controlled way.
    thanks for the cool vids. keep it up.

  • @robwatson826
    @robwatson826 2 года назад

    Great video. When I first started with React and discovered that the whole page re-rendered when I updated a form input, I started obsessing over limiting the re-renders - I even ended up building a pub/sub state manager to limit it.
    Then it dawned on me that the re-renders are so fast and heavily optimised under the hood already that it's really not a problem.
    I would cry if I saw that uncontrolled input app you created here in a production system that I needed to maintain, the controlled inputs are so much easier to work with.

  • @atreysinainadkarni5453
    @atreysinainadkarni5453 Год назад

    This is a very common use case which we normally don't pay much attention to. Thanks for clearing this up .

  • @gmoniava
    @gmoniava 2 года назад +3

    If render speed is concern (can happen with large forms) you can still go with state based approach, wrap the form elements in custom component and apply React.memo to the custom component.

  • @TheRcfrias
    @TheRcfrias 2 года назад

    Great explanation!, I kind of understand where those comments are coming from. I used to blame re-rendering all the time, and it turned out the bug was somewhere else. I’d suggest to those guys to check if they are making the same mistake I was doing of writing functional components inside the parent functional component. That messes everything and makes you believe the rerendering is the problem, but it’s not, just replacing those to the top of the file (outside the parent functional component function) will fix most of the issues.

  • @ThePenitentOneArg
    @ThePenitentOneArg 2 года назад +12

    I'm not an "avoid all rerenders" fundamentalist, but I think I know why people told you in the last video not to use controlled inputs.
    There is a case when you have a select input that you are populating it with that comes from something like:
    {options.map(o => }
    In this particular case, for every key stroke you do, this map will have to rerender all the options again, and again, and again... If you have 3 options, this could be imperceptible, but let's say you have 30 or 40 options (a countries select for example), every key stroke will have to rerender all the form and 40 options needlessly.
    Now let's suppose you have more than one select, and it's not a plain html select input, but it is some fancy select with styles and other things... That could be pretty bad for the performance, and it's actually perceptible.
    You can do this test: grab your phone, and write "hello world" in an input, then, hold pressed the "delete" button, and you will see that the app will get unresponsive for a few moments while it's deleting the text. And that's because is rerendering multiples selects with lots of options. It had to delete and re render 440 options elements.
    I know this is a very particular case, but this kind of situations made me realize that it is important only to grab the form data on submit event, and not before. This is not a "good practice" it's just a good approach for a very particular case .
    Lastly, I would say that you are assuming that everything will perform perfectly because you are running that app on your Mac. At least in other countries (my particular case is latin america), assuming that all users will have an iphone is very bad. That's why that "it's an imperceptible 4ms rerender" could become much worse in some cases.
    Sorry for the text wall, I'm not teaching nothing to anyone, I just wanted to share a different point of view and to say that this thing about "uncontrolled forms" is something that is good in some cases, but I agree that maybe having the most readable code is gonna win unless performance is critically important

    • @WebDevCody
      @WebDevCody  2 года назад +10

      I’ll test it out with 400 list items. I can see your concern with a page with a ton of components of items, but I’d also argue why does your user need to see 400 things on a page at a time, there should be some additional ux design to add filters, pagination, or another approach. My point is use a ref when you actually see performance issues and not as a “best practice”

    • @masiafmasiaf2204
      @masiafmasiaf2204 2 года назад

      i'll said is uncontrolled and controlled is a tool u just lean to when to used it, i have work on a project with lot of input and selector with 20+option and validation ( some validation depend on other input), also calculation that depend on input, it became damn slow, a first the legacy code was a massive form where the input pull from, then i change it to state colocation i think its called, basically you move the state of that input in the input component, so every rerender will be that input, not the whole set of input, and it go way more faster and in the end i have used react hook form ( i think in the doc they use uncontrolled under the hood, dont remember) with same calculation, validation, and it get slow also, same solution, state colocation. dont know if this will help you in your next react form build.

    • @cyrilvorontsov3335
      @cyrilvorontsov3335 Год назад +1

      While it's true that this code calculates .map() every time, rendering the result is a whole different story. That's what 'key' attributes are for: they are matched with their previous same-key snapshots and NOT rerendered if equal.

  • @youssefaserrar2001
    @youssefaserrar2001 2 года назад +3

    I always use Formik+Yup for forms, it renders everything when an input changes which is ok, it's soo good for error handling and input types.

  • @piotrekjazz1287
    @piotrekjazz1287 Год назад

    The other thing is that the rerendering is optimized in such a way that it takes place on the elements that change, not the whole component is rerendered. The whole component is checked but not built from scrach on every change. Therefore the extra code and functions from refs might slow it down too

  • @failure232
    @failure232 Год назад

    Thank you for nice explanation. How can i see video from the begging of current video?

  • @dolahav3007
    @dolahav3007 2 года назад +2

    In your example, you are correct. However, a lot of people using some sort of a react ui library.
    If you adjust your code to use mui TextFields wrapped by an mui Grid, the site becomes slow even with 10 rendered inputs.
    We could argue that using ui libraries such as mui is not a good idea in the first place, but it is a good example for when you would want to use uncontrolled inputs even with a small amount of inputs.

    • @dolahav3007
      @dolahav3007 2 года назад +1

      In this case, minimizing re-renders with a library such as react-hook-form is a good idea. It allows the usage of controlled inputs while minimizing the amount of components that get re-renders on every interaction with the form.

    • @WebDevCody
      @WebDevCody  2 года назад +1

      Sounds like mui is the issue, but yes I can see your concerns

  • @jatinhemnani1029
    @jatinhemnani1029 2 года назад

    Your channel is really helpful.. keep on posting

  • @lookingforbino
    @lookingforbino Год назад

    Hi Cody, another question off the topic, I am wondering how you gonna type the form object, give it like 30 pairs?

  • @sprioleau
    @sprioleau 2 года назад +3

    Well said, good sir. Thanks for talking about the nuance about the speed of renders vs. the maintainability of the code.
    I was recently told that another reason for trying to "optimize" or "eliminate" rerenders is in the case where a child component has some side effect (like an API call or some sort of low-level DOM manipulation) that you don't want to happen each time the parent is rerendered. In my case, we were using Ant Design to build out a UI, so the child component wasn't specifically authored by anyone in my team.
    So, I was advised to use the useMemo hook when passing an array as a child component prop so that the child didn't rerender as a result of the reference to the array changing.
    Do you have any thoughts about this argument...namely, eliminate rerenders when child components may have side effects that you may not want to run?

    • @WebDevCody
      @WebDevCody  2 года назад +2

      I think the child having side effects might be more of the issue. I’d need more info, but the child should not rerun code due to a rerender. The child should be using a callback or memo or something. Since you don’t have control over that third party component, a memo might be all you can do

  • @planetmall2
    @planetmall2 2 года назад +2

    Great job.

  • @markpinero
    @markpinero 2 года назад +1

    I feel this example isn’t doing the uncontrolled components any justice by only replacing controlled components with manual JS. There is built-in form validation in the browser. By adding `required` to the input fields and adding CSS `input:invalid { border: 1px red solid; } input:invalid + div { display: block }`. But if you need the heavy lifting of custom validation, yes, use controlled components. The browser has a lot of these things built-in if you know what to look for.

    • @WebDevCody
      @WebDevCody  2 года назад

      right, I mean most applications I've been on require custom / complex validation rules where depending on the previous select box or check box you have enabled, the validation rules on the form will change and what is displayed on the page will change. So html input validation rules can only take you so far. But I get your point.

  • @jesuscc9225
    @jesuscc9225 2 года назад +2

    tip not very related with the video:
    const handleSubmit = (e) => {
    e.preventDefault();
    const data = Object.fromEntries(new FormData(e.target));
    }
    that gets all the values in an object of the inputs that are in a form and have a name attribute, is very easy to use and its uncontrolled, I like to use it with vanilla js

    • @WebDevCody
      @WebDevCody  2 года назад +1

      yeah this is a cool tip, I think I've done that before

  • @HamedAthari
    @HamedAthari 29 дней назад

    We can use library like reaft-hook-form to prevent rendering

  • @Atif1702
    @Atif1702 2 года назад

    Amazing, can't agree more 💯 These people are really annoying who run after saving a few ms and nanoseconds. They are still living in 80s and 90s.
    Optimize only when needed and you have run and tested both the solutions.

  • @lookingforbino
    @lookingforbino Год назад

    Thanks for the demo.
    I just duplicated your code locally. I found that the form renders immediately every time I type a single letter in the input. Then I have to use mouse the focus back to the place I just wrote the letter, then it re-render again.
    I need to re-focus again and again in order to write a word. How do I fix this.
    Btw, const keys = Object.keys(initialFormData) is pretty neat.
    Solution:
    I am thinking usually no such thing will happen if I use e.preventDefault() inside onSubmit. This video is for the demonstration of re-rendering, the question above is really irrelevant, sorry for that.

  • @AmirHameed-picwellwisher12pk
    @AmirHameed-picwellwisher12pk 2 года назад +1

    What about the case when a change in an input triggers a big change in the parent or sibling component?

    • @WebDevCody
      @WebDevCody  2 года назад +1

      Then yeah you might look into uncontrolled inputs at that point. But I guess what “big change” could happen on a parent or child because of typing? If typing into an input causes your page to lag, there might be something wrong with the design of your form or you have too many components?

    • @AmirHameed-picwellwisher12pk
      @AmirHameed-picwellwisher12pk 2 года назад

      @@WebDevCody I had made a browser extension to manage browser tabs, it had a search feature to search in URLs and titles. And you can guess, on search/change it filter relevant tabs and highlight text on these tabs. Although my approach was fine, I believe I could make it even better or make it async or use debounce.

    • @WebDevCody
      @WebDevCody  2 года назад +1

      @@AmirHameed-picwellwisher12pk yeah I think a debounce is what you want. Using uncontrolled would still require sometype of debounce to know what the user is done typing so that you could trigger the state change.

    • @AmirHameed-picwellwisher12pk
      @AmirHameed-picwellwisher12pk 2 года назад

      @@WebDevCody right,
      thanks for quick reply :)

  • @amans6504
    @amans6504 2 года назад

    i think i like using the react-hook-form library, it takes care of the re-renders & error-handlingd. That being said, i'd pick controlled inputs over refs. Ref is just like manipulating the dom directly, that's a bad practice for forms, that's not what refs were meant for

  • @haiderimam8977
    @haiderimam8977 2 года назад

    Very very nice video, thank you so much. Just curious can you please tell or better yet make a video on a real life scenario where uncontrolled forms might be a better option.

  • @ilijanl
    @ilijanl 2 года назад

    Great video, especially that you should considering code maintenance before pre optimalisation. However consider using react-hook-form since it provides far more things than just form state, like only showing errors on submit, dirty state, auto focus on errors (after submit), validation abstraction and more to provide a better UX for end user.

    • @WebDevCody
      @WebDevCody  2 года назад +2

      yes, I typically use react-hook-form on my own personal projects where validation rules are not too complex

  • @snjvthakur24
    @snjvthakur24 4 месяца назад

    For controlled input my input loosing focus due to re rendering from parant

  • @MaverickDriver95
    @MaverickDriver95 4 месяца назад

    When going with an uncontrolled approach you need to really lean into the html output. Rely on patterns and css attributes to handle these things rather than javascript. This will make it so you have much less code to write as you won't need the useEffect at all

  • @cas818028
    @cas818028 2 года назад +1

    While I agree that rerenders "can be an after thought, given the speed of rerender's". For the devs that are used to answering the interview questions and are always optimizing to get things to O(1) I am sure the additional rerenders are like nails on a chalkboard. Its also probably a good habit to get used to avoiding rerenders if you can, because at some point your likely to transition to Next.js for some project. And rerenders do matter here, especially with server side components.

    • @Rulito2405
      @Rulito2405 2 года назад

      Can you elaborate more on the different behaviour between Next and rerendering compared to React and rerendering?

    • @WebDevCody
      @WebDevCody  2 года назад +1

      it's premature optimizations in most cases. If your app is slow, speed it up. Otherwise you'll be adding useMemo, React.memo, useCallbacks, and refs everywhere which makes your code even harder to understand

    • @ExpDev69
      @ExpDev69 2 года назад

      @@Rulito2405 there is none, actually, there's less to worry about. You usually want to be vary of rerenders when a child component does some API calls etc, but with Nextjs there are ways where the API call won't fire every rerender, but persist over them.

  • @Ndzzle
    @Ndzzle Год назад

    Re-rendering is so fast that the user hasn't let go of the right mouse button by the time it's complete.

  • @abel090713
    @abel090713 2 года назад

    If you somehow got to a point where you are worrying about re-renders it's probably better to use memo to only re-render what is updated.

  • @blovio
    @blovio 2 года назад

    Hey I really like your videos :D I have been trying to figure out the best way to make a form for like a week. I think this is a contentious question because there are so many ways to do it. However, I'd like to make the case for useRef one last time.
    If you need to make a form with a submit button, you don't need to do all of this instantaneous error checking in place. When you press submit you can check if the DOM nodes exist (by checking the Refs are not null). This allows you to use semantic html and guarantee that the nodes are present when you press submit.
    import { useRef } from 'react';
    export default function Form() {
    const textInput = useRef(null)
    const phoneInput = useRef(null)
    const emailInput = useRef(null)
    function handleSubmit(e) {
    e.preventDefault()
    if (textInput.current && phoneInput.current && emailInput.current) {
    const submitObj = {}
    submitObj.text = textInput.current.value;
    submitObj.phone = phoneInput.current.value;
    submitObj.email = emailInput.current.value;
    console.log(submitObj);
    }
    }
    return (
    handleSubmit(e)}>
    name

    phone
    Format: 123-456-7890

    email


    )
    }
    If you want to do error handling and stuff on the fly then I think controlled components are a much better use case, but I don't really see the problem with refs as long as you guarentee the nodes are on the page. Let me know what you think, love your stuff!
    edited: for the if statement it should be .current, I updated it.

    • @WebDevCody
      @WebDevCody  2 года назад +1

      I don’t see what the ref is helping you achieve there that you can’t do with an onChange and state variable. Also, most forms I’ve made for businesses require validation, so you should add validation in your example to make it realistic and see how much of a pain validation becomes to set and clear the error outline and text. If refs work for you, keep using them, but I don’t find them as concise as a solution.

    • @blovio
      @blovio 2 года назад

      ​@@WebDevCody There is validation, it's baked into the or pattern props, but I agree with you for the most part, I think onChange and useState is the way to go most of the time, but if you just need a very simple form with basic html validation, then i've found refs to be useful.

  • @Valyssi
    @Valyssi 2 года назад

    Good points, and I'm not sure where the "controlled components are bad practice"-advice (which directly contradicts the docs) comes from, but I think it might be from a Web Dev Simplified video. No shade towards the guy, but he sometimes makes videos that go against the advice of the docs without justifying those choices or even referring to the docs which makes me think he might simply not read them. Other than that I know his videos help a lot of people, but IMO that approach to making content is irresponsible, which is why I'm glad you referred to the docs and used the profiler.

  • @xpamamadeus
    @xpamamadeus 2 года назад

    U have app for customer that can control multiple shops,shops have working hours and lets say some have 24/7.U need to control that by inputs.
    Now some calculations customer have around 200 shops and they all need to be listed in one component and thats 4800 inputs and can say thats average customer.
    Now u have 24 master inputs for every hour that can copy values to every hour sites if u get lucky that customer wants something universal for shops for that pratucular day soo u need only to put values once and they apply to all sites and u can do that in 24 inputs its 15 sec work.
    Now some of that sites sometimes want different values so inputs must stay there...
    Just did some test and try with controlled inputs on test customer with only 2 sites its around 120ms with ofc 24 rerenders and can its bad situation.
    Soo point is that there are use case when u cannot use controlled if u have like specific app.but ofc for user forms like name,address etc its fine.

  • @ricko13
    @ricko13 Год назад

    interesting 👍

  • @jowarnis
    @jowarnis 2 года назад +1

    A lot of these misconceptions come from Web Dev Simplified viewers.. He recently made a video about how you supposed to be using uncontrolled inputs for forms.

    • @WebDevCody
      @WebDevCody  2 года назад

      I’ll need to watch it and see if he makes any good points.

    • @jowarnis
      @jowarnis 2 года назад

      @@WebDevCody it's in this video "Are You Making This React State Mistake?". Doesn't give any good arguments just talks about rerenders.

    • @ElektrykFlaaj
      @ElektrykFlaaj 2 года назад

      @@jowarnis this dude is annoying in 90% of his videos

  • @hernancorrea2146
    @hernancorrea2146 2 года назад

    You are right, please do more performance explaining videos.

  • @musaddikrayat
    @musaddikrayat 2 года назад

    React Hook Form used to do uncontrolled inputs in the past, but now they use controlled inputs from v6 and minimize the re-renders. Not sure though!😕

    • @John-mj1kk
      @John-mj1kk 2 года назад +1

      What? They're still using uncontrolled inputs. react-hook-form has a component if you need to use controlled inputs.

  • @hombacom
    @hombacom 2 года назад

    Use classes instead of cluttered style manipulation? With all different ways to solve form handling it seems to be a good idea to have a global solution or perspective for forms. Has it happened before that it feels at least great on my high-end dev computer? ;-)

    • @WebDevCody
      @WebDevCody  2 года назад

      Yes we can use classes as well to toggle the styles, but the underlying boilerplate code to add and remove either styles or classes remains the same.

  • @joaomendoncayt
    @joaomendoncayt 2 года назад

    The uncontrolled components use case has to do with prop drilling handlers and trying to update state on possibly unmounted components.

    • @WebDevCody
      @WebDevCody  2 года назад

      How can an unmounted input trigger a state change?

    • @joaomendoncayt
      @joaomendoncayt 2 года назад

      @@WebDevCody the other way around. An input triggering a state change on a possibly unmounted component.
      I can't recall correctly but I've dealt with a similar problem before, and doesn't really make sence to me either but I remember finding out about "uncontrolled inputs" from that problem.

    • @WebDevCody
      @WebDevCody  2 года назад

      @@joaomendoncayt right but this still seems like a scenario where you switch to uncontrolled components in a particular scenario instead of just always using uncontrolled inputs right?

    • @joaomendoncayt
      @joaomendoncayt 2 года назад

      @@WebDevCody for sure! Ahahah
      You are so programmed to reading hateful little kids comments that you take everything with such a defensive approach. Take it easy bud 💪
      My bad on using the comment section as like a casual chat, should've hoped on discord

    • @WebDevCody
      @WebDevCody  2 года назад +1

      @@joaomendoncayt haha yeah you’re are 💯 correct I get too defensive. It’s very hard to read into the intent of these comments sometimes. A lot of them are written to just try and make the content creator feel stupid, but yeah have a discussion with me on discord, RUclips comments kind of suck

  • @Evikeuklavier
    @Evikeuklavier 2 года назад

    Sometimes I like using uncontrolled components, but if it comes down to readability, maintainability, etc I would definitely use controlled.

    • @ElektrykFlaaj
      @ElektrykFlaaj 2 года назад +1

      yeah.
      And with Formik's useFormik/useField combo you absolutely can eliminate any prop passing, just pass a name to useField somewhere 10 children levels deep down the useFormik's component and you have access to a field's state. That's the beauty of React

  • @iivarimokelainen
    @iivarimokelainen 2 года назад

    Good points, but uncontrolled doesn't mean you can't set styles based on state. You could even set the defaultValue, and it still would be an uncontrolled input. Uncontrolled means no onChange, and not setting value based on state, that's all

    • @WebDevCody
      @WebDevCody  2 года назад

      Yeah that’s true, I think I was more trying to address the people who try to say uncontrolled inputs are faster because the onChange rerenders the component due to state update which I argue is a non issue for the most part. I think uncontrolled inputs have a good use case, but simply using them because “controlled inputs are slow” isn’t an accurate reason.

  • @ElektrykFlaaj
    @ElektrykFlaaj 2 года назад

    I always cringe when people tell me i should swap Formik for React Hook Form because Formik is slow/controlled.
    Never had issues with Formik performance on production (it sometimes runs slow on dev, but only in dev), and I did some big multipage forms using a single useFormik and tested them on old android phones and they worked fine.

    • @WebDevCody
      @WebDevCody  2 года назад

      A lot of people talk about performance but don’t understand what is too slow to ship vs what is perfectly fine to ship

    • @ElektrykFlaaj
      @ElektrykFlaaj 2 года назад

      @@internet4543 in which way?

    • @ElektrykFlaaj
      @ElektrykFlaaj 2 года назад

      @@internet4543 have you even tried to use useFormik/useField with Formik? You can easily basically build a multipage form without a single prop passing. Just pass a name to a formik field component and you have a field connected, with errors and touched states and all functions needed to manually modify a field's state. I don't undestand how is destructuring register("name") a cleaner way
      You pass all initial values, validation, submit function and all other form configs to a useFormik, so it's really dead easy to manage complex forms

  • @failscript
    @failscript 2 года назад

    Basically a soft skills problem. People are like: "Hey, actually is a bad practice if you don't do things the way I do", like, fuck documentation and context of application.

  • @alexandrepereira6522
    @alexandrepereira6522 2 года назад +3

    You’re showing a very bad example for uncontrolled inputs. There is at least one use case for uncontrolled inputs and it was the one for your beginner react challenge. If you don’t need to do onChange input validation and just need a ref to the value, uncontrolled inputs are okay.

    • @WebDevCody
      @WebDevCody  2 года назад +1

      Idk, I’d still use a controlled input for that example so that my code base is consistent. The point of react is to have the state drive the dom. When you use refs you are by passing that paradigm and managing updates yourself.

  • @SeibertSwirl
    @SeibertSwirl 2 года назад

    Good job babe!!!!

  • @darelbvcr687
    @darelbvcr687 Год назад

    noticed you watch andrew tate on youtbe good work!

    • @WebDevCody
      @WebDevCody  Год назад

      Was trying to figure out why he is popular lol

  • @ev3rybodygets177
    @ev3rybodygets177 Год назад

    just use signals

  • @truthseeker2236
    @truthseeker2236 2 года назад

    Lol they gave horriable idea. Might as well go back to jquery at that point.

  • @evgeny6692
    @evgeny6692 2 года назад

    Uncontrolled inputs make no sense due to amount of boilerplate and vanila js, why bothering yourself with that if you are already using react :D

    • @evgeny6692
      @evgeny6692 2 года назад

      The only usecase for uncontrolled inputs I can think of would be some huge grid with crazy amount of data and editable cells

    • @WebDevCody
      @WebDevCody  2 года назад

      Yeah, I think they have legit use cases because react is slow when you have a lot of components on a page, especially if you’re using some type of component library that goes heavy on component based design, but for most use cases a controlled input works well and is easier to manage

  • @cyrilvorontsov3335
    @cyrilvorontsov3335 Год назад

    And have you guys tried covering your form with Jest unit test for submit event? For, like, an uncontrolled form that collects user inputs by addressing form.[name].value inside onSumbit? Go give it a try. Pure Node env, as it turns out, doesn't respect this at all. The pain I'm here because of, and currently trying to solve without changing our forms to controlled. Wish me good luck lol.