使用无状态功能组件与调用方法之间的区别是什么?

时间:2016-02-03 22:03:36

标签: javascript reactjs ecmascript-6

我试图了解无状态组件以及这些示例之间的区别:

class App {
  render() {
    return (
      <div>
        {this.renderAFunction('hello')}
      </div>
    );
  }
  renderAFunction(text) {
    return (
      <p>{text}</p>
    );
  }
}

和此:

class App {
  render() {
    return(
      <div>
        <RenderAFunction text='hello'/>
      </div>
    );
  }
}

const RenderAFunction = ({text}) => (
    <p>{text}</p>
);

或者是否有任何差异?

3 个答案:

答案 0 :(得分:5)

功能上,绝对没有区别。两者最终都会呈现一个段落元素,但还有其他方面需要考虑。在研究这两种方法时,有三点要做(在我看来):

  • 可重用性:您需要了解在需要时分离组件。如果renderAFunction只是为了生成一些基于API请求的JSX,那么它在方法中就可以了。但是如果你想在其他地方重用它,那么将它分成它自己的组件。 React的很大一部分是组件可重用性并且摆脱了代码重复。将方法分离到它自己的组件中是必要的。
  • 目的:有理由使用无状态功能组件,并且没有理由。无状态功能组件的重点是没有状态和表现。如果您需要执行涉及React生命周期或内部状态的操作,请将其保留为方法或新类,具体取决于您是否希望它可重用。
  • 性能:使用无状态功能组件的效率会降低。这是因为它是一个组件,而不仅仅是从方法返回的一些JSX。截至目前,React团队计划对无状态功能组件进行一些优化,因为它们不包含状态且仅仅是表示性的,但这可能直到React Fiber完成后才会发生,因此您的无状态功能组件与常规的完整类组件相比没有优化。与返回某些JSX的方法相比,这使得它非常低效,特别是如果它只是在另一个组件中使用过一次。

一个好的经验法则是问问自己,我是否需要在其他任何地方使用它?如果没有,那么将其保存在方法中。如果你在其他任何地方都不需要它,那么将JSX分成一个单独的组件将会有更差的性能,并且不会遵循React的核心原则。

如果您在其他地方需要它,那么请将组件分开,以便遵循React的可重用性概念。

答案 1 :(得分:2)

您的App's render函数将转换为您的第一个示例的以下JS代码:

render() {
   return React.createElement(
     'div',
     null,
     this.renderAFunction('hello')
   );
 }

以下是第二个:

render() {
  return React.createElement(
    'div',
    null,
    React.createElement(RenderAFunction, { text: 'hello' })
  );
}

虽然它们看起来几乎相同,但有一个显着的区别:懒惰React仅在将RenderAFunction主体安装到DOM层次结构时执行const LazyApp = () => { const heavy = <div><HeavyStuff /></div> // ... return <div>done it</div> } const HardWorkingApp = () => { const heavy = <div>{HeavyStuff()}</div> // ... return <div>done it</div> } const HeavyStuff = () => { // ... do heavy rendering here } 主体。

你的情况是微不足道的,但成像如下:

Components

懒惰的应用程序根本不会执行任何繁重的工作。也许从那个合成的例子中不清楚为什么人们会做这样的事情。但是有一些现实世界的例子,当概念上相似的东西(创建 20170606002857 AddDeviseToAdmins 20170606130509 AddUserRefToGoals ` root@debian:/home/zeeroday/github/Build-in-Progress-Web# bundle exec rake db:drop root@debian:/home/zeeroday/github/Build-in-Progress-Web# bundle exec rake db:setup -- create_table("activities", {:force=>true}) -> 0.1371s -- add_index("activities", ["owner_id", "owner_type"], {:name=>"index_activities_on_owner_id_and_owner_type"}) -> 0.0910s -- add_index("activities", ["recipient_id", "recipient_type"], {:name=>"index_activities_on_recipient_id_and_recipient_type"}) -> 0.0911s -- add_index("activities", ["trackable_id", "trackable_type"], {:name=>"index_activities_on_trackable_id_and_trackable_type"}) -> 0.0909s -- create_table("admin_users", {:force=>true}) -> 0.1411s -- add_index("admin_users", ["email"], {:name=>"index_admin_users_on_email", :unique=>true}) -> 0.0909s -- add_index("admin_users", ["reset_password_token"], {:name=>"index_admin_users_on_reset_password_token", :unique=>true}) -> 0.0910s -- create_table("categories", {:force=>true}) -> 0.0992s -- create_table("categorizations", {:force=>true}) -> 0.0908s -- add_index("categorizations", ["category_id", "project_id"], {:name=>"index_categorizations_on_category_id_and_project_id", :unique=>true}) -> 0.0910s -- add_index("categorizations", ["category_id"], {:name=>"index_categorizations_on_category_id"}) -> 0.0907s -- add_index("categorizations", ["project_id"], {:name=>"index_categorizations_on_project_id"}) -> 0.0910s -- create_table("collectifies", {:force=>true}) -> 0.0993s -- add_index("collectifies", ["collection_id", "project_id"], {:name=>"index_collectifies_on_collection_id_and_project_id", :unique=>true}) -> 0.0907s -- add_index("collectifies", ["collection_id"], {:name=>"index_collectifies_on_collection_id"}) -> 0.0910s -- add_index("collectifies", ["project_id"], {:name=>"index_collectifies_on_project_id"}) -> 0.0908s -- create_table("collections", {:force=>true}) -> 0.1238s -- add_index("collections", ["slug"], {:name=>"index_collections_on_slug"}) -> 0.0742s -- create_table("comments", {:force=>true}) -> 0.1249s -- add_index("comments", ["commentable_id", "commentable_type"], {:name=>"index_comments_on_commentable_id_and_commentable_type"}) -> 0.0825s -- add_index("comments", ["user_id"], {:name=>"index_comments_on_user_id"}) -> 0.0827s -- create_table("decisions", {:force=>true}) -> 0.0825s -- create_table("delayed_jobs", {:force=>true}) -> 0.1244s -- add_index("delayed_jobs", ["priority", "run_at"], {:name=>"delayed_jobs_priority"}) -> 0.0825s -- create_table("design_files", {:force=>true}) -> 0.0828s -- create_table("edits", {:force=>true}) -> 0.0826s -- create_table("favorite_projects", {:force=>true}) -> 0.0910s -- create_table("follows", {:force=>true}) -> 0.1492s -- add_index("follows", ["followable_id", "followable_type"], {:name=>"fk_followables"}) -> 0.0907s -- add_index("follows", ["follower_id", "follower_type"], {:name=>"fk_follows"}) -> 0.0827s -- create_table("friendly_id_slugs", {:force=>true}) -> 0.0827s -- add_index("friendly_id_slugs", ["slug", "sluggable_type"], {:name=>"index_friendly_id_slugs_on_slug_and_sluggable_type", :unique=>true}) -> 0.0826s -- add_index("friendly_id_slugs", ["sluggable_id"], {:name=>"index_friendly_id_slugs_on_sluggable_id"}) -> 0.0825s -- add_index("friendly_id_slugs", ["sluggable_type"], {:name=>"index_friendly_id_slugs_on_sluggable_type"}) -> 0.0826s -- create_table("images", {:force=>true}) -> 0.1241s -- create_table("news", {:force=>true}) -> 0.1822s -- create_table("placements", {:force=>true}) -> 0.0909s -- create_table("projects", {:force=>true}) -> 0.1740s -- create_table("projects_users", {:id=>false, :force=>true}) -> 0.0083s -- add_index("projects_users", ["project_id", "user_id"], {:name=>"index_projects_users_on_project_id_and_user_id"}) -> 0.0823s -- create_table("questions", {:force=>true}) -> 0.0911s -- create_table("remarks", {:force=>true}) -> 0.1241s -- create_table("sessions", {:force=>true}) -> 0.1324s -- add_index("sessions", ["session_id"], {:name=>"index_sessions_on_session_id"}) -> 0.0825s -- add_index("sessions", ["updated_at"], {:name=>"index_sessions_on_updated_at"}) -> 0.0827s -- create_table("settings", {:force=>true}) -> 0.1578s -- add_index("settings", ["target_type", "target_id", "var"], {:name=>"index_settings_on_target_type_and_target_id_and_var", :unique=>true}) -> 0.0820s -- create_table("sounds", {:force=>true}) -> 0.1573s -- create_table("steps", {:force=>true}) -> 0.1241s -- add_index("steps", ["ancestry"], {:name=>"index_steps_on_ancestry"}) -> 0.0825s -- create_table("users", {:force=>true}) -> 0.1492s -- add_index("users", ["authentication_token"], {:name=>"index_users_on_authentication_token", :unique=>true}) -> 0.0823s -- add_index("users", ["confirmation_token"], {:name=>"index_users_on_confirmation_token", :unique=>true}) -> 0.0826s -- add_index("users", ["email"], {:name=>"index_users_on_email", :unique=>true}) -> 0.0908s -- add_index("users", ["reset_password_token"], {:name=>"index_users_on_reset_password_token", :unique=>true}) -> 0.0827s -- add_index("users", ["unlock_token"], {:name=>"index_users_on_unlock_token", :unique=>true}) -> 0.0826s -- create_table("versions", {:force=>true}) -> 0.1491s -- add_index("versions", ["item_type", "item_id"], {:name=>"index_versions_on_item_type_and_item_id"}) -> 0.0825s -- create_table("videos", {:force=>true}) -> 0.1574s -- initialize_schema_migrations_table() -> 0.1017s -- assume_migrated_upto_version(20170605230006, ["/home/zeeroday/github/Build-in-Progress-Web/db/migrate"]) -> 0.8765s You have 2 pending migrations: 20170606002857 AddDeviseToAdmins 20170606130509 AddUserRefToGoals Run `rake db:migrate` to update your database then try again. ` 而不渲染它们)发生时。

答案 2 :(得分:0)

基本上,两者都有同样的目的。但创建组件的真正优势在于其可重用性。

如果你必须为这个组件渲染那个特定的jsx片段。然后,不需要创建单独的组件。