简体   繁体   中英

Custom react dropdown component re-rendering on every user input

I'm having a bit of trouble with controlling the amount of re rendering done by React. Say I've got this user input right here:

handleFirstNameChange: function(e) {
    this.setState({ firstName: e.target.value, userTyping: true });
},
render: function(){
<RB.Input value={this.state.firstName} onChange={this.handleFirstNameChange} name=""
                    type="text" label="First name" placeholder="First name.."/>
}

And this custom dropdown component:

<SearchDropdown title="Role" options={this.props.currentUser.roles} 
                            selectedOptions={this.props.currentUser.selectedRoles} />

Every single time the user inputs a letter, the dropdown will re render every single option, even though (as it seems) the components have nothing common to each other. I've been trying to manage this by including a "userIsTyping" boolean as a prop to the dropdown component and checking it in ComponentShouldUpdate but it's becoming more of a problem now that I've got nested components. I'm still in my early stages of using React so I'm pretty sure there's something obvious here that I'm missing.

With React, onChange fires every time a key is pressed. In your code, this will in turn cause a call to setState via the handleFirstNameChange handler, and that will cause a re-render.

Two options:

  1. Don't worry about it. Re-rendering isn't necessarily going to cause you any problems, and if there's no performance issue then you could just ignore this. Your component is fairly simple if I were in your shoes I'd probably just forget about it :)
  2. Don't use onChange , use onBlur and then your handler will only fire when the field loses focus.

You can read more about the behaviour of onChange in React in the documentation:

https://facebook.github.io/react/docs/forms.html#interactive-props

React was designed to intelligently compute the most efficient DOM manipulations that would be required to get the desired output, so it isn't really a problem that your component is being re-rendered so often.

It looks like you're using onChange to update your component's state whenever your input has a different value. Might I recommend the LinkedStateMixin ? This way, you could force a particular state to always be consistent with some value in an input.

render: function(){
<RB.Input valueLink={this.linkState.firstName} name=""
                    type="text" label="First name" placeholder="First name.."/>
}

In that code above (assuming that RB.Input behaves the same way as a typical input ), your component's firstName state will always be equivalent to whatever value contained within your input.

You can manage re-render conditions for a React component by adding the lifecycle method shouldComponentUpdate to your class.

I'm not sure what conditions would actually require a re-render of the dropdown in your application, but you can specify those conditions for react like this:

var SearchDropdown = React.createClass({

    // ... (your existing code)

    shouldComponentUpdate: function(nextProps, nextState) {
        // Do a boolean compare; re-render only if this returns true
        return this.props.options.somethingToCheck !== nextProps.options.somethingToCheck;
    }
});

Docs: https://facebook.github.io/react/docs/component-specs.html#updating-shouldcomponentupdate

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM