【问题标题】:ReactJS Functional Component vs Component Functions for conditional rendering用于条件渲染的 ReactJS 函数式组件与组件函数
【发布时间】:2017-09-29 03:51:52
【问题描述】:

有时我想将我的条件渲染移出render(),而我总是在这两种方法之间进退两难:

class MyComponent extends React.Component {
  _renderSomething() => {
    const {x, y, z} = this.props
    // conditional rendering based on props
  }

  render() {
    return (
      { this._renderSomething }
      // vs
      { renderSomething(this.props) }
      // which one is better?
    )
  }
}

const renderSomething = (props) => {
    const {x, y, z} = props
    // conditional rendering based on props
}

export default MyComponent

_renderSomethingthis.renderSomething 之间的性能差异?

我应该什么时候使用哪个?

【问题讨论】:

  • 一个非常好的问题!我很好奇……不过还有另一种选择。你可以创建一个全新的组件,然后像 <MyComplexComponent {...props}> 一样调用它。您可以将其作为功能组件。
  • 我认为如果我们直接使用 _renderSomething() 那么我们需要该函数的实例来访问道具。但是在 --const renderSomething...--我们不需要这个关键字
  • 这是基于意见的,如果没有看到 “复杂的条件” 部分,很难给您建议 - 正是这些复杂性有助于指导我们愿意做出的权衡当我们考虑一种方法而不是另一种方法时
  • 一般来说,无状态组件应该只是一个纯函数,它接受 props 并返回要渲染的组件——担心函数 fthis.f 是一个微优化,不应该被视为如何构建代码的主要指南 - 允许这样的事情来决定代码的结构表明根本缺乏理解
  • @naomik 感谢您的洞察力 naomik。我明白你来自哪里。然而,我关心的并不是诸如fthis.f 之类的微优化。忘记复杂的渲染部分吧,这不是我的主要关注点。让我们假设 条件渲染 是一个简单的嵌套 if-else。我的重点是功能组件将被转换为_createClass(renderSomething,[{}]) 之类的东西,而内部功能将只是另一个var _renderSomething = function...。这里有什么不同吗?似乎功能组件更昂贵?

标签: reactjs rendering


【解决方案1】:

函数组件与函数返回元素之间存在性能损失。一个例子就是这样 -

// Component approach
let Tab = ({label, link}) => <li><a href={link}>{label}</a></li>;

class Tabs extends Component {
    render(){
        return (
            // notice the key prop is handled by parent render
            <ul>{this.props.tabs.map(tab => <Tab {...tab} key={link}>)}</ul>
        )       
    }
}

// function based approach, notice the key prop is handled by the function
let tab = ({label, link}) => <li key={link}><a href={link}>{label}</a></li>;

class Tabs extends Component {
    render(){
        return (
            <ul>{this.props.tabs.map(item => tab(item))}</ul>
        )       
    }
}

在组件示例中,您最终会得到不必要的中间 Tab 组件,它们会添加到 vdom 中,无论它们多么小。然后随着它们的增长,这些组件最终会导致渲染缓慢。 React 需要在后续渲染中跟踪这些组件。这些是功能组件,您将无法访问基于 shouldComponentUpdate 的优化。

函数版本不会受此影响,因为它直接返回Elements,而不是组件。此外,对于较小的函数,代码内联也会带来好处。

对此方法的扩展讨论是here

【讨论】:

    【解决方案2】:

    一般来说,无状态组件应该是一个纯函数,只返回要渲染的组件

    下面,您可以将&lt;EmptyList /&gt; 替换为&lt;ul&gt;&lt;/ul&gt;,但想法是您可以在任何您认为有必要的地方进行抽象——在这种情况下,我认为为空列表提供一些占位符文本会很好,所以制作它无状态功能组件是一个简单的选择

    你的应用程序实际上需要状态的很少——事实上,你应该尽可能地删除它。当什么都不需要状态时,一切都可以用函数来表达

    const EmptyList = ({ placeholder = "There are no items to display" }) =>
      <ul><li>{ placeholder }</li></ul>
    
    const ListItem = ({ text = "" }) =>
      <li>{ text }</li>
    
    const List = ({ items = [] }) =>
      items.length === 0
        ? <EmptyList />
        : <ul>{ items.map (text => <ListItem text={text} />) }</ul>
        
    ReactDOM.render(<List items={[1,2,3]} />, document.querySelector('#list1'))
    ReactDOM.render(<List items={[]} />, document.querySelector('#list2'))
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
    <div id="list1"></div>
    <div id="list2"></div>

    【讨论】:

      猜你喜欢
      • 2021-03-08
      • 2019-03-30
      • 2020-07-14
      • 2019-04-15
      • 2019-01-01
      • 1970-01-01
      • 2019-04-25
      • 1970-01-01
      相关资源
      最近更新 更多