反应每个开发人员都应该知道的最佳实践和技巧。 第一部分

哈Ha! 我向您介绍了Alex Devero的文章“每个React开发人员都应该知道的反应最佳实践和技巧” Pt。1

图片

React是用于构建交互式用户界面的最受欢迎的库之一。 在本文中,我将向您展示一些React最佳实践的示例,这些示例将帮助您成为更好的开发人员。 查看这些说明,以更好地编写React代码。

内容:

  1. 保持组件小
  2. 避免堆积组件
  3. 减少有状态组件的使用
  4. 使用带有挂钩和备注的功能组件,而不是类上的组件
  5. 请勿在原始状态下使用道具。

结束语:每个开发人员都应该了解的最佳实践和技巧第1部分

1.保持组件小


使组件保持较小是React可以创造奇迹的最佳实践之一。 实施这种看似简单的做法可以帮助您编写更简洁,更可维护的代码。 更不用说它可以帮助维持理由,或者至少可以保留理由。

您可以使用一种公认的经验法则。 看一下render方法。 如果它的行数超过10,则您的组件可能太大,并且是重构和拆分为几个较小组件的理想选择。 请记住,使用React的想法之一或其部分思想是重用代码。

目标是创建您编写一次的代码,然后在需要时一次又一次地使用它们。 从这个角度来看,将所有数据组合成一个庞大的组件,一个文件是没有意义的。 而且,即使您真的不在乎可重用的代码,也请考虑一下。 支持数百行代码的组件有多容易支持?

这样的组件将难以维护,调试和更新。 这也意味着与此组件进行任何工作都将花费更长的时间。 换句话说,您的整体表现会受到影响。 迟早它会让您发疯。 否则它将使您的队友和同事发疯,并且他们将开始使您发疯。

无论您选择什么,都将很快失去理智,甚至可能为自己成为敌人。 这不值得。 保持组件较小。 保持友谊,理智,时间和生产力。 简化调试,更新和维护代码。 考虑一个例子。



/// // file: index.jsx import React from 'react' const books = [ { category: 'Business', price: '$20.00', name: 'Private Empires', author: 'Steve Coll' }, { category: 'Philosophy', price: '$25.00', name: 'The Daily Stoic', author: 'Ryan Holiday' }, { category: 'Sport', price: '$15.95', name: 'Moneyball', author: 'Michael Lewis' }, { category: 'Biography', price: '$21.00', name: 'Titan', author: 'Ron Chernow' }, { category: 'Business', price: '$29.99', name: 'The Hard Thing About Hard Things', author: 'Ben Horowitz' }, { category: 'Fiction', price: '$4.81', name: 'Limitless: A Novel', author: 'Alan Glynn' } ] class Bookshelf extends React.Component { render() { const tableRows = [] this.props.books.forEach((book) => { tableRows.push( <tr> <td>{book.name}</td> <td>{book.author}</td> <td>{book.price}</td> <td>{book.category}</td> </tr> ) }) return ( <div> <form> <input type="text" placeholder="Search..." /> <button>Search</button> </form> <table> <thead> <tr> <th>Name</th> <th>Author</th> <th>Price</th> <th>Category</th> </tr> </thead> <tbody>{tableRows}</tbody> </table> </div> ) } } // Render Bookshelf component ReactDOM.render(<Bookshelf books={booksData} />, document.getElementById('container')) 

已成为

 /// // file: books-data.js const books = [ { category: 'Business', price: '$20.00', name: 'Private Empires', author: 'Steve Coll' }, { category: 'Philosophy', price: '$25.00', name: 'The Daily Stoic', author: 'Ryan Holiday' }, { category: 'Sport', price: '$15.95', name: 'Moneyball', author: 'Michael Lewis' }, { category: 'Biography', price: '$21.00', name: 'Titan', author: 'Ron Chernow' }, { category: 'Business', price: '$29.99', name: 'The Hard Thing About Hard Things', author: 'Ben Horowitz' }, { category: 'Fiction', price: '$4.81', name: 'Limitless: A Novel', author: 'Alan Glynn' } ] export default booksData /// // file: components/books-table.jsx import React from 'react' class BooksTable extends React.Component { render() { const tableRows = [] this.props.books.forEach((book) => { tableRows.push( <tr> <td>{book.name}</td> <td>{book.author}</td> <td>{book.price}</td> <td>{book.category}</td> </tr> ) }) return ( <table> <thead> <tr> <th>Name</th> <th>Author</th> <th>Price</th> <th>Category</th> </tr> </thead> <tbody>{tableRows}</tbody> </table> ) } } export default BooksTable /// // file: components/search-bar.jsx import React from 'react' class SearchBar extends React.Component { render() { return ( <form> <input type="text" placeholder="Search..." /> <button>Search</button> </form> ) } } export default SearchBar /// // file: components/bookshelf.jsx import React from 'react' // Import components import BooksTable from './components/books-table' import SearchBar from './components/search-bar' class Bookshelf extends React.Component { render() { return ( <div> <SearchBar /> <BooksTable books={this.props.books} /> </div> ) } } export default Bookshelf /// // file: index.jsx import React from 'react' // Import components import Bookshelf from './components/bookshelf // Import data import booksData from './books-data' // Render Bookshelf component ReactDOM.render(<Bookshelf books={booksData} />, document.getElementById('container')) 

2.避免堆积组件


每个规则都应谨慎应用。 这也适用于这些React最佳实践,尤其是前一个。 对于组件,可以很容易地重写它,甚至可以以组件的形式编写最小的代码。 不要这样做。 使每个段落,span或div成为组件是没有意义的。
在开始将每个组件分成小部分之前,请三思。 您可以将组件视为“ HTML”的混合,它只做一件事,就是独立的,用户会整体上看待它。 将这段代码作为组件有意义吗? 如果不是,请结合使用此代码。 否则,将其拆分。

让我们看一些例子来说明这个组件的定义。 一个例子是情态对话。 该组件可以包含许多小元素,例如div,标题,文本段落,按钮等。 从理论上讲,所有这些元素都可以分为小部分。

实际上,这是没有意义的。 是的,其中一些元素可以彼此独立存在。 但是,创建只包含一个段落或一个标题的组件真的有用吗? 接下来会发生什么? 标签,输入甚至跨度的组成部分? 这种方法是不可持续的。

幸运的是,还有另一种方法可以查看此情况。 您可以使用原子设计方法作为指导。 在原子设计中,一切都分为六类:原子,分子,生物,模板,页面和实用程序。 您从最小的元素开始,例如按钮,链接,快捷方式,输入等。 这些是原子。

然后,您将原子组合并创建分子。 分子的示例可以是模式对话框,表单,弹出窗口,下拉菜单,导航等。 此外,您可以将一个分子与另一个分子或与一个原子结合在一起以创建生物。 生物体的一个例子是标题,产品清单或购物篮。 模板,页面和实用程序不再重要。

如何将原子设计与这两个React组件最佳实践示例结合在一起? 让我们不要复杂化。 组件可以是原子以外的任何东西,即 分子,生物或什至是模板或页面(如果限制到最大)。 从这个意义上说,标签,标题,段落不是组成部分,因为它们是原子。
但是,模式对话框,表单,弹出窗口,下拉列表等。 是成分,因为它们都与分子或生物类别有关。 仍有一些可疑的元素,例如按钮。 是的,从原子结构的角度来看,它是一个原子。 但是,它可以独立存在,并且有很多变体,并且仍然可以正常工作。

在这种情况下,我建议不要考虑React的最佳做法,而应以我的内在本能为指导。 最后,将由您来处理代码。 重要的是您要舒服。 因此,不要盲目地遵循一些最佳做法。 如果您在团队中工作? 与您的同事分享您对此的想法。

3.减少有状态组件的使用


这是已经应用了一段时间的最佳React实践之一。 但是,随着React 16.8.0和React钩子的出现,这种做法变得越来越流行。 在此之前,当您想使用状态或任何生命周期方法时,还必须使用有状态组件。 没有别的办法了。

弯钩改变了这一点。 在它们正式发布之后,React开发人员不再局限于有状态的组件,因为他们需要使用状态。 多亏了钩子,React开发人员现在可以根据需要使用状态甚至生命周期方法来编写无状态组件。

为什么这很重要? 就性能而言,无状态或功能组件通常比有状态组件更好。 原因是没有状态或生命周期方法。 换句话说,更少的代码可以执行和编译。 当然,如果您正在做一些非常小的项目,则这种差异几乎是不明显的,几乎是看不见的。

但是,这些细小的差异可能随着您的项目的发展而加总。 还考虑一下有状态组件与功能组件相比需要多少行代码。 该功能也更短,通常更易于阅读。 让我们看一下按钮组件,它被定义为具有状态控制和功能的组件。 您更喜欢哪一个?

 // Button defined as a stateful component class Button extends React.Component { handleClick = () => { // Do something } render() { return( <button type="button" onClick={this.handleClick}>Click me</button> ) } } // Button defined as a functional component const Button = () => { const handleClick = () => { // Do something } return( <button type="button" onClick={handleClick}>Click me</button> ) } 

4.使用带有挂钩和备注的功能组件,而不是类上的组件


正如我们已经讨论的,您不再需要仅使用状态组件来使用状态。 而且,一些React开发人员还相信,将来,React将开始远离类。 是真的,现在没关系。 重要的是,借助钩子,一个功能组件现在可以使用状态。
其次,使用功能组件具有其优势。 TLDR? 没有类,继承和构造函数。 没有这个关键字。 严格的反应最佳实践。 高信噪比。 肿胀的组件和不良的数据结构更容易发现。 该代码更易于理解和验证。 而且,性能也更好。

还有一件事。 许多React开发人员反对功能组件。 问题之一是,作为React开发人员,您在使用功能组件时无法控制渲染过程。 当某些更改时,React返回一个功能组件,无论该组件本身是否已更改。
过去,解决方案是使用纯组分。 清洁组件提供了比较状态和道具的功能。 这意味着React可以“检查”组件,道具或组件本身的内容是否已更改。 如果是这样,他将退还它。 否则,它将跳过重新渲染,并将重用上次渲染的结果。 更少的渲染等于更好的性能。
使用React 16.6.0,这不再是问题,并且针对功能组件的参数不再有效。 改变局面的是备忘录。 备忘录对功能组件进行了浅浅的比较,可以“检查”组件,道具或组件本身的内容是否已更改。

同样,基于此比较,React将返回组件或重用上次渲染的结果。 简而言之,备忘录可让您创建“干净”的功能组件。 不再有任何理由使用有状态组件或纯组件。 至少如果您不需要处理困难的情况。

在这种情况下,您应该考虑使用更具可扩展性和可管理性的产品,例如MobX,Redux或Flux,而不是组件的状态。 另一个可能的选择是使用上下文。 无论如何,多亏了钩子和备忘录,功能组件无疑是一些值得考虑的最佳React实践。

5.不要在原始状态下使用道具


这是我开始学习时想要了解的最佳React实践之一。 然后我不知道在初始状态下使用道具是一个非常糟糕的主意。 为什么这是个坏主意? 问题在于,在组件创建期间,构造函数仅被调用一次。

这意味着当您下次对道具进行一些更改时,组件的状态将不会更新。 它将保留其以前的含义。 然后我错误地认为道具与国家同步。 因此,当某些细节发生变化时,状态将发生变化以反映此变化。 不幸的是,事实并非如此。

如果您希望状态在初始渲染期间仅从props接收一次值,并且可以控制组件内部的状态,则这可能不是问题。 否则,您可以使用componentDidUpdate解决此问题。 顾名思义,这种生命周期方法使您可以在某些事物(例如道具)发生变化时更新组件。

如果决定使用此方法,请记住一件事。 它不会涉及初始渲染,而仅涉及下一个渲染。 因此,请确保使用必要的值(可能是从道具获得的值)来初始化组件的状态。 然后使用componentDidUpdate来更新这些值和所需的组件。

结束语:每个开发人员都应该了解的最佳实践和技巧第1部分


恭喜你! 您刚刚完成了有关React最佳实践的本迷你系列文章的第一部分。 今天,您已经了解了可以用来使React代码更短,更简单,更好,更快,更容易阅读和维护的五种实践。 现在由您决定实施您同意的实践并开始使用它。

在下一部分中,您将了解一组不同的最佳实践和技巧,以帮助您改善React代码以及编程技能。 在此之前,请把握今天所学的知识,并花一些时间进行练习。

如果您喜欢这篇文章,请订阅。

最初发布到Alex Devero博客。

Source: https://habr.com/ru/post/zh-CN465685/


All Articles