【问题标题】:Should functions within React functional components be wrapped?React 函数式组件中的函数应该被包装吗?
【发布时间】:2021-08-24 22:39:41
【问题描述】:

我有一个功能组件,其中包含一个功能,renderMessages

const MessageContainer = (props) => {
     const renderMessages = () => {
        return props.messages.map((message, index) => {
            return(
                <Message
                    key={index}
                    username={message.username}
                    message={message.message}
                    fromCurrentUser={message.fromCurrentUser}
            />);
        })
    }

     return(
          <div className='messages'>
               {renderMessages()}
          </div>
     )

}

但是,我意识到,与其在地图上包装 renderMessages 函数,我可以:

const renderMessages = props.messages.map((message, index) => {
     return(
          <Message
               key={index}
               username={message.username}
               message={message.message}
               fromCurrentUser={message.fromCurrentUser}
            />);
      })
}

因此,我的最终回报将只包含

return(
     <div className='messages'>
          {renderMessages}
     </div>
)

在基于类的组件和渲染函数中,我会使用两者中的最后一个。使用功能组件时,这两者中的哪一个被认为是最佳实践,为什么?

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    编辑:

    在使用功能组件时,两者中哪一个被认为是最佳实践,为什么?

    最佳实践随上下文而变化 - 例如您正在工作的团队 - 所以这是一个基于意见的问题。

    话虽如此,在我看来,我也不会这样做。我会(而且我会)这样做:

    const MessageContainer = (props) => {
    
    
         return (
              <div className='messages'>
                {props.messages.map((message, index) => (
                      <Message
                          key={index}
                          username={message.username}
                          message={message.message}
                          fromCurrentUser={message.fromCurrentUser}
                      />
                 ))}
              </div>
         )
    
    }
    

    额外变量的目的是什么?

    当您使用它时,don't use indexes for keys

    关于你在类组件上封装渲染逻辑的所有额外方法的肮脏秘密是它们是一种反模式——这些方法实际上是组件。

    编辑#2

    正如另一个答案中所指出的,对于这个特定用例,最高效的解决方案是在功能组件之外指定 map 函数:

    const renderMessage = (message,index) => (
      <Message
       key={index}
       {...message}
      />
    )
    
    const MessageContainer = (props) => {
      return (
       <div classname='messages'>
         {props.messages.map(renderMessage)}
       </div>
      );
    }
    

    但是,您不应该过早地进行优化,我会提倡我发布的原始解决方案纯粹是为了简单/可读性(但是,对于他们自己而言)。

    【讨论】:

      【解决方案2】:

      很好地将映射分离到组件的返回之外,因为这样你只会一遍又一遍地调用相同的函数,直到 .map 完成迭代,但是如果你将它写在组件的返回中,每次.map 遍历下一个项目,您将创建一个新函数。 关于这个问题,我推荐第二种方式,干净/可读的代码总是更可取的。

      附:尝试使用唯一的消息 ID 而不是索引。

      【讨论】:

      • 为什么使用变量与将完全相同的代码内联到 return 语句会改变“map”的语义?
      • 不是'map'的语义,而是函数本身,大多数情况下你应该在组件的返回之外声明函数,所以你只声明它们一次并且总是重用相同的引用。当你在里面声明函数时,每次渲染组件时都会重新定义函数。所以;如果页面重新渲染 3 次,则必须声明一个新的匿名函数 3 次,但如果您在外部声明它,您将调用相同的函数 3 次,因此相比之下,拥有 1 个引用比重新声明一个更好每次都有新功能。
      • 好的,完全同意。这种挑剔的性能在现实世界的大多数情况下不太可能成为问题,但仍然有效。但是,如果您仔细观察,OP 并没有将它与 return 语句分开,因为 renderMessages 使用 **props**.messages.map - 所以它仍然在功能组件内部。问题实际上是关于使其成为组件内部的可调用函数,而不是将结果分配给变量。
      • 它在功能组件内部,而不是它的返回语句。现实世界的项目有 100 多个组件,所以每当我们处理现实世界的项目时,我们需要使函数集中化、可重用、可读且易于调试,而且我们必须压缩每一毫秒的代码。
      • 我不清楚您是否理解正在讨论的两个选项:将其放在功能组件的主体中并将其分配给变量与将其直接放在 return 语句中是 100% 等效的.
      猜你喜欢
      • 2018-02-25
      • 2022-11-06
      • 2019-12-01
      • 1970-01-01
      • 2021-09-29
      • 2020-01-27
      • 1970-01-01
      • 1970-01-01
      • 2022-10-02
      相关资源
      最近更新 更多