React开发人员的五个最佳组件框架

作者 : IT 大叔 本文共4954个字,预计阅读时间需要13分钟 发布时间: 2020-09-11

有很多方法可以使代码结构化,使其易于阅读,并且每个人都有自己的方式到达那里。问题就变成了,有没有最好的方法呢?

在本文中,我将讨论针对React开发人员的五个最常见的最佳实践。React的设计旨在按照您所需的方式进行定制-这是没有根据的!因此,如果这五个“最佳实践”场景不适合您,那么完全可以找到自己的方法。我希望您能摆脱别人目前正在“思考中的思考”的方式。

我们将讨论的最佳实践是:

  • 目录组织
  • 组件和关注点分离
  • 处理状态
  • 抽象化
  • 命名约定

React开发人员的五个最佳组件框架插图目录组织

React文档提到,通常有两种主要方法来组织React应用程序:按功能或路由分组按文件类型分组。这里的关键是不要考虑太多。

如果从较小的应用程序开始,则可以按照适合自己的方式自然地组织代码。请记住,React并非自以为是,所以事情的结构由100%决定。只要您对文件的组织方式有一个逻辑上的解释,那其实并不重要。

但是,由于React文档提到了这两种组织策略,因此让我们看一下每种策略以了解它们的结构。假设我们有一个电子商务应用程序,该应用程序具有用户,产品列表,详细的产品页面,购物车和结帐流程。

功能如何布置?

按功能分组

根目录是src目录,它是React应用程序中两个基本目录之一(公用文件夹是另一个)。在src目录中,我们将在文件夹的根目录中包含基本文件App.jsindex.js文件。然后,我们将为您的应用程序中的每个功能嵌套目录。

就事物的组织方式而言,您的举动可能会有所不同:它可能具有更多目录,更少目录,甚至可能进一步嵌套到组件,样式和测试中。

src/
App.js
App.css
App.test.js
index.js
global/ ⇐ items that are in common with entire application
  AppContext.js
  ThemeContext.js
  UserContext.js
  Button.js
cards/
  index.js
  Cards.css
  Cards.js
  Card.css
  Card.js
  Card.test.js
detailed-product/
    DetailedProduct.css
  DetailedProduct.js
  DetailedProduct.test.js
checkout/
  ReviewOrder.css
  ReviewOrder.js
  ReviewOrder.test.js
  ShoppingCart.css
  ShoppingCart.js
  ShoppingCart.test.js  
user/
  index.js
  User.css
  User.js
  User.test.js

以下是一种约定。如果文件按文件类型分组,组织将如何看待?

按文件类型分组

根目录仍然是src目录。客户端将看到呈现到屏幕的所有内容仍保留在此文件夹中。和以前一样,我们将App.jsand index.js文件保留在该目录的根目录中,然后具有代表应用程序组成部分的目录:组件,上下文,css,hook和测试。

src/
App.js
index.js
components/
  App.css
  Card.js
  Cards.js
  ConfirmationPage.js
  DetailedProduct.js
  Footer.js
  Navbar.js
  ReviewOrder.js
  Settings.js
  ShoppingCart.js
  User.js
context/ 
  AppContext.js
  ThemeContext.js
  UserContext.js
css/
  Card.css
  Cards.css
  ConfirmationPage.css
  DetailedProduct.css
  Footer.css
  Navbar.css
  ReviewOrder.css
  Settings.css
  ShoppingCart.css
  User.css
hooks/
  useAuth.js
  useAxios.js
  ...other custom hooks
tests/
  App.test.js
  Card.test.js
  Cards.test.js
  ConfirmationPage.test.js
  DetailedProduct.test.js
  Footer.test.js
  Navbar.test.js
  ReviewOrder.test.js
  Settings.test.js
  ShoppingCart.test.js
  User.test.js

与以前一样,项目的设置方式取决于您的应用程序以及实现方式。这里的基本结构取决于文件的类型,仅此而已。最终,应该使文件结构更容易浏览。您的操作方式取决于您。

组件和关注点分离

在使用React Hooks之前,很容易发现什么是有状态类组件还是表述性功能组件。一些开发人员也将它们称为“智能”组件与“哑”组件。当然,智能组件是承载状态和处理逻辑的组件,而哑组件是纯粹接受分配给它们的道具的组件。

在React Hooks出现和Context API更新之后,大多数事物都可以被视为功能组件,这引发了关于何时分离包含本地状态的组件,不包含本地状态的组件以及如何处理的讨论。

最终,由您和/或您的团队决定如何构造设计模式,但是最佳实践倾向于使逻辑和局部状态组件与静态组件保持独立

处理状态和道具

React应用程序中的数据流非常重要。有两种处理数据的方式:使用状态将状态作为道具传递。让我们看一下最佳实践。

处理状态时,无论是在上下文API中是全局的还是在本地中,都不得通过使用新值在state上重新分配属性来直接对其进行更改:

 addOne = () => { //Don’t use this!!!!
   this.state.counter += 1;
 }

而是在处理类组件中的状态时,使用该this.setState()方法来更新状态。

import React from "react";
import "./styles.css";
 
class Counter extends React.Component{
 constructor(props) {
   super(props);
   this.state = {
     counter: 0
   }
 }
 
 addOne = () => {
   this.setState({counter: this.state.counter + 1})
 }
 
 subtractOne = () => {
   this.setState({counter: this.state.counter - 1});
 }
 
 reset = () => {
   this.setState({ counter: 0 });
 }
 render() {
   return (
     <div className="App">
       <h1>Simple React Counter</h1>
       <h2>{this.state.counter}</h2>
       <button onClick={this.addOne}> + </button>
       <button onClick={this.reset}> Reset </button>
       <button onClick={this.subtractOne}> - </button>
     </div>
   );
 }
}
 
export default Counter;

使用React Hooks时,将使用您命名的任何set方法:

import React, { useState } from "react";
import "./styles.css";
 
export default function App(){
 
 const [ counter, setCounter ] = useState(0);
 const addOne = () => {
   setCounter(counter + 1)
 }
 
 const subtractOne = () => {
   setCounter(counter - 1);
 }
 
 const reset = () => {
   setCounter(0);
 }
   return (
     <div className="App">
       <h1>Simple React Counter</h1>
       <h2>{counter}</h2>
       <button onClick={subtractOne}> - </button>
       <button onClick={reset}> Reset </button>
       <button onClick={addOne}> + </button>
 
     </div>
   );
}

道具

当处理道具并将状态传递给要使用的其他组件时,可能会出现一个点,您需要将道具传递五个孩子。这种将道具从父母代传给孩子几代的方法称为道具钻探,应该避免。

虽然如果您将道具传递给下一代,代码肯定会起作用,但它容易出现错误,并且数据流可能很难遵循。最好是如果需要让子级访问几代后的状态,则应该使用Redux或Context API(目前使用Context API是更简单,更可取的方式)为全局状态管理创建某种设计模式

抽象化

可重用性做出积极反应。在谈论React最佳实践时,抽象这个词经常出现。抽象意味着大型组件或应用程序的某些部分可以被拿走,制成自己的功能组件,然后导入到较大的组件中。使组件尽可能地简单,通常使其仅用于一个目的,这增加了代码可重用的机会。

在上面创建的简单计数器应用程序中,有机会从App组件中抽象出一些元素。可以将按钮抽象为它们自己的组件,在其中我们将方法和按钮标签作为道具传递给他们。

应用程序的标题和标题也可以包含在它们自己的组件中。在我们将所有内容抽象化之后,App Component可能看起来像这样:

import React, { useState } from "react";
 
import { Button } from "./Button";
import { Display } from "./Display";
import { Header } from "./Header";
import "./styles.css";
 
export default function App(){
  const addOne = () => {
   setCounter(counter + 1)
 }
 
 const subtractOne = () => {
   setCounter(counter - 1);
 }
 
 const reset = () => {
   setCounter(0);
 }
 
 const initialState = [
   {operation: subtractOne, buttonLabel:"-"},
   {operation: reset, buttonLabel: "reset"},
   {operation: addOne, buttonLabel: "+"}
 ]
 const [ counter, setCounter ] = useState(0);
 const [ buttonContents,  ] = useState(initialState)
    return (
     <div className="App">
       <Header header="Simple React Counter"/>
       <Display counter={counter}/>
       {buttonContents.map(button => {
         return (
           <Button key={button.operation + button.buttonLabel} operation={button.operation} buttonLabel={button.buttonLabel} />
         )
       })}
     </div>
   );
}

抽象的主要目的是使子组件尽可能通用,以便可以按您需要的任何方式对其进行重用。应用程序组件应仅包含特定于应用程序的所有信息,并且仅呈现或返回较小的组件。

命名约定

React中有三个主要的命名约定,应被视为最佳实践。

  1. 组件应使用PascalCase –也应使用 camelCase大写,并以其功能命名,而不是以特定的应用程序功能命名(以防稍后更改)。
  2. 需要密钥的元素应该是唯一的,非随机的标识符(例如单个卡片或CardDeck或List中的条目)。最佳做法是不要仅将索引用于键。具有由两个不同的对象属性串联而成的键分配是合法的。

    密钥的基本目的是存储基本信息,以便React可以了解应用程序中发生的变化。

key={button.operation + button.buttonLabel} 
  1. 方法应在camelCase中,并应根据其功能命名,而不应特定于应用程序。出于与PascalCase中组件相同的原因,应该为它们的目的而不是在应用程序中的功能来命名方法。
免责声明:
1. 本站资源转自互联网,源码资源分享仅供交流学习,下载后切勿用于商业用途,否则开发者追究责任与本站无关!
2. 本站使用「署名 4.0 国际」创作协议,可自由转载、引用,但需署名原版权作者且注明文章出处
3. 未登录无法下载,登录使用金币下载所有资源。
IT小站 » React开发人员的五个最佳组件框架

常见问题FAQ

没有金币/金币不足 怎么办?
本站已开通每日签到送金币,每日签到赠送五枚金币,金币可累积。
所有资源普通会员都能下载吗?
本站所有资源普通会员都可以下载,需要消耗金币下载的白金会员资源,通过每日签到,即可获取免费金币,金币可累积使用。

发表评论