【问题标题】:Custom react dropdown component re-rendering on every user input自定义反应下拉组件在每个用户输入上重新呈现
【发布时间】:2015-08-31 05:12:14
【问题描述】:

我在控制 React 完成的重新渲染量时遇到了一些麻烦。 假设我在这里有这个用户输入:

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.."/>
}

还有这个自定义下拉组件:

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

每次用户输入一个字母时,下拉菜单都会重新呈现每个选项,即使(看起来)组件之间没有任何共同点。 我一直在尝试通过将“userIsTyping”布尔值作为下拉组件的道具并在 ComponentShouldUpdate 中检查它来管理这个问题,但现在我已经有了嵌套组件,这变得越来越成问题。 我仍处于使用 React 的早​​期阶段,所以我很确定这里有一些明显的东西我遗漏了。

【问题讨论】:

    标签: javascript reactjs reactjs-flux react-jsx


    【解决方案1】:

    使用 React,onChange 会在每次按下某个键时触发。在您的代码中,这反过来会导致通过handleFirstNameChange 处理程序调用setState,这将导致重新渲染。

    两种选择:

    1. 别担心。重新渲染不一定会给您带来任何问题,如果没有性能问题,那么您可以忽略这一点。如果我在你的鞋子里,你的组件相当简单,我可能会忘记它:)
    2. 不要使用onChange,使用onBlur,然后你的处理程序只会在字段失去焦点时触发。

    您可以在文档中阅读更多关于 onChange 在 React 中的行为的信息:

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

    【讨论】:

    • 问题是这些自定义下拉列表中的一些包含从父组件传递下来的多达 300 个元素,并且每个表单段最多有 6 个下拉列表,因此重新渲染实际上花费了我相当多的费用。我用 SearchDropdown 组件中的状态变量替换了“UserTyping”变量,该变量管理下拉菜单是否处于活动状态,因此现在运行得更加顺利,感谢您的帮助。
    【解决方案2】:

    React 旨在智能地计算获得所需输出所需的最有效的 DOM 操作,因此您的组件被如此频繁地重新渲染并不是真正的问题。

    看起来您正在使用onChange 来更新组件的状态,只要您的输入具有不同的值。我可以推荐LinkedStateMixin 吗?这样,您可以强制特定状态始终与输入中的某个值保持一致。

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

    在上面的代码中(假设RB.Input 的行为方式与典型的input 相同),您的组件的firstName 状态将始终等同于您输入中包含的任何值。

    【讨论】:

      【解决方案3】:

      您可以通过将生命周期方法 shouldComponentUpdate 添加到您的类来管理 React 组件的重新渲染条件。

      我不确定哪些条件实际上需要在您的应用程序中重新呈现下拉菜单,但您可以像这样指定这些条件进行反应:

      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;
          }
      });
      

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

      【讨论】:

        猜你喜欢
        • 2023-01-31
        • 2021-07-11
        • 2023-02-14
        • 2023-02-01
        • 1970-01-01
        • 2021-12-03
        • 2020-12-28
        • 2012-12-12
        • 1970-01-01
        相关资源
        最近更新 更多