question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Concern over onChange of several components

See original GitHub issue

I have been using material UI for over 2 years now and I have come to realize a possible design flaw to be discussed. Many of our forms are inline inside of one main render class with many input boxes and other complicated components and sometimes with <TextField/> components, things sometimes can render slow because our main form component has to re-render on each keypress from a user. This is because our onChange event is a typically a setState to set the state of the bound value to pass as props to each component we bind to.

  • This is a v1.x issue (v0.x is no longer maintained).
  • I have searched the issues of this repository and believe that this is not a duplicate.

Expected Behavior

I wanted to discuss some kind of possible change to allow the values to change inside of the component rather than making the caller pass value as a prop. By making the caller setState and set value into the parent state and passing it along as props, you have to re-render all sibling components who might hold state for other nodes just to get the value to be set according to what someone types.

Here is an example component which takes the value within the component rather than always relying on props passed to set the value, where its appropriate in this case to just set the value of the parent onBlur where a render could occur after all has been typed.

class Input extends BaseComponent {
  constructor(props, context) {
    super(props, context);
    this.state = {
      value: props.value,
      style: props.style
    };
  }
  render() {
    return <input style={this.state.style} key="input-label2" maxLength={this.props.maxLength} type='text' className='form-control' value={this.state.value}
    onChange={(e) => {
      this.setState({value: e.target.value});
    }}
    onBlur={() => {
      this.props.onBlur(this.state.value);
    }}/>
  }
}

I mostly just wanted opinions on this topic and maybe I can send a pull request of (at least for input boxes) allowing a version which sets the state within the component internally so that the parent setState doesnt re-render the entire (slow form if there are a lot of nodes).

My opinion is that its not an ideal practice to only rely on props to setState and not keep the state of values internal to your component. I have formed this opinion after years of seeing a slow typing response where my entire forms get progressively slower because material UI only relies on props passed to set the value. Each developer has to abstract your input boxes to their own component setting state to get it to work more efficiently to not render the entire “sibling form component”

Thank you for your time and thoughts on this matter. Maybe I am just doing something wrong and I am open to feedback of something I might be doing wrong.

Cheers!

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

4reactions
davidrennecommented, Jun 6, 2018

For anyone in the same boat as our team where sometimes forms render slow/sluggish for TextField component and you come across this thread, here is an example abstraction which is stateful and isolated to just rendering that node and not all the nodes in your form.

https://gist.github.com/davidrenne/28e123e27417f3326aee18363f69bc77

3reactions
oliviertassinaricommented, Jun 21, 2018

I have formed this opinion after years of seeing a slow typing response where my entire forms get progressively slower because material UI only relies on props passed to set the value.

@davidrenne This problem highlights the limitation of the brute-force approach. Updating the whole form component at each keystroke doesn’t scale. But you are not the first one to face it. People have been building abstractions since the beginning of React to address it. I would encourage you to pick one of the popular React form library (react-final-form, react-redux, formik). You won’t have this problem. They provide abstractions to keep each form field controlled and performant by scoping the updates.

I wanted to discuss some kind of possible change to allow the values to change inside of the component rather than making the caller pass value as a prop.

It’s not something we will fix at the Material-UI level. As @mbrookes stated, we have designed the current situation on purpose, we are well aware of the tradeoff and happy with it.

Read more comments on GitHub >

github_iconTop Results From Across the Web

how to write a onchange event for a returned component
This the correct way to do it. These points to follow: You should not create the function inside render. you need to create...
Read more >
onChange returns the selected value, not the complete event
onChange simply returns the new value and label and not the whole event. I understand we can use the hidden input field to...
Read more >
Handle onChange | Learn ReactJS in steps Episode 3
Visit http://bigbinary.com/videos/learn-reactjs- in -steps/handle- onchange for episode notes.
Read more >
Using the Effect Hook - React
Hooks let us split the code based on what it is doing rather than a lifecycle method name. React will apply every effect...
Read more >
onChange not working with custom React TextField component
I've attempted a number of different approaches - none of which seem to work. My best guess is that though the onChange property...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found