reactjs - 在 React render 方法中定义新函数的实际成本是多少?

标签 reactjs

我试图阐明在 React 的 render 方法中使用新函数声明的优点/缺点。

考虑如下的渲染方法:

  render () {
    return (<SomeComponent somePropWithoutEventBind={() => console.log('not so dangerous?')} />)
  }

在上面的示例中,somePropWithoutEventBind 没有绑定(bind)到 DOM 事件:react 将检查 prop 更改,并且每次调用 render 时此 prop 都会发生更改 - 因为它是一个新函数 - 所以它与以前的不一样,这个很贵,但没什么了不起的。

现在在这种情况下

  render () {
    return (<input onChange={() => console.log('dangerous?')} />)
  }

onChange prop 确实绑定(bind)到 DOM(执行类似于 addEventListener 的操作),因此每个渲染都必须 removeEventListener再次addEventListener?这是避免在 render 方法中声明函数的主要原因吗?

如果可能,请证明您的答案指向 react 源代码。

最佳答案

避免在渲染中定义新函数的主要原因是避免过度渲染。

考虑将新函数绑定(bind)到 DOM 元素(react 元素不是真正的 DOM),如下所示: <button onClick={_ => this.setState({ hide: true })}>Hide Me</button>}几乎没有任何成本,因为 DOM 元素无论如何都会重新渲染。 (站点注释:react 不使用像 add/removeEventListener 这样的原生 DOM 事件,它使用 SyntheticEvent 并且您的代码针对虚拟 DOM,又名 React 元素,而不是真正的 DOM)

但是对于自定义组件(在大型代码库中,我们通常有许多由功能/类子组件组成的复杂容器组件。假设您有类似的东西

render() {
  // you won't run into unnessary re-render issue 
  // when you use `onClick={this.handleClick}` since the function reference doesn't change
  // while most perf tricks done by react bindings are relying on shallow compare of props/state
  return (
    <ComplexContainer onClick={_ => this.setState({ forceReRender: true})}>
      <Child1 />
      <Child2>
        <NestedChild1 />
        <NestedChild2 />
      </Child2>
    </ComplexContainer>
  )
}

如果您这样做,这将导致从 ComplexContainer 开始的整个渲染树重新渲染,这可能会对性能产生显着的负面影响,但您将需要 DevTools 分析来进行基准测试。

事实上,我真正想说的是:它可能没有你担心的那么大,避免过早优化可能更重要。尝试一下这个很棒的阅读 Material :React, Inline Functions, and Performance

<子> 有关 React 合成事件系统的更多信息请参见此处,它只是 native DOM 事件的包装器,用于规范不同浏览器供应商之间事件的细微差异。 API 是相同的 event.preventDefault()/event.preventPropagation()等按原样工作,但您可以免费获得跨浏览器兼容性。关于其内部工作原理请参见event delegation

关于reactjs - 在 React render 方法中定义新函数的实际成本是多少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48549290/

相关文章:

javascript - 如何将 vaadin-icon 导入 React 组件?

css - react 悬停/事件/焦点样式CSS选择器不适用于封闭元素

reactjs - Typescript:如何在 React 中为历史对象添加类型检查?

javascript - 在回调中返回函数(事件,用户数据)?

javascript - Redux-thunk 调度功能在 Laravel 上不起作用

javascript - 模拟 Redux 操作中的函数

javascript - 在 ReactJS 中遇到多个事件状态的问题

javascript - 为什么 event.target.value 只捕获字符串输入中的第一个字母

javascript - font-awesome 不显示带有 React 和 Webpack 的图标(仅正方形)

reactjs - 自定义过滤器 ag 网格 react