>웹 프론트엔드 >JS 튜토리얼 >React 컴포넌트를 구축하는 가장 완벽한 방법

React 컴포넌트를 구축하는 가장 완벽한 방법

小云云
小云云원래의
2018-01-23 10:55:031579검색

저는 React의 가장 큰 장점은 충분히 간단하다는 점이라고 생각하기 때문에 React를 매우 좋아합니다. 단순한 것과 쉬운 것에는 차이가 있습니다. 즉, React도 쉽다는 뜻입니다. 물론, 핵심 내용을 익히고 나면 다른 모든 것이 제자리를 찾을 것입니다. 더 어려운 부분은 아래에서 다루겠습니다.

결합 및 응집력

이러한 지표(결합 및 응집력)는 프로그래밍 습관을 바꾸는 데 다소 어려움을 가져옵니다. 클래스 기반 객체 지향 프로그래밍에 자주 사용됩니다. 또한 React 컴포넌트를 작성할 때에도 동일한 규칙을 참조하고 적용할 것입니다.

커플링은 요소 간의 상호 연결 및 종속성을 나타냅니다. 한 요소를 변경하고 다른 요소를 동시에 업데이트해야 하는 경우 이를 긴밀한 결합이라고 합니다. 느슨한 결합이란 한 요소가 변경되면 다른 요소를 변경할 필요가 없음을 의미합니다. 예를 들어 은행 이체 금액 기능을 보여줍니다. 표시된 금액이 환율 계산에 의존하는 경우 내부 변환 구조가 변경되면 표시된 코드가 업데이트됩니다. 요소 인터페이스를 기반으로 느슨하게 결합된 시스템을 설계하면 요소의 변경 사항이 뷰 레이어 표시에 영향을 미치지 않습니다. 분명히 느슨하게 결합된 구성 요소는 관리 및 제어가 더 쉽습니다.

응집력은 구성 요소가 한 가지만 담당하는지 여부입니다. 이 지표는 단일 원칙과 Unix 원칙을 따릅니다. 즉, 한 가지에 집중하고 이를 잘 수행하는 것입니다. 형식화된 계정 잔액 표시를 위해 관련 환율을 계산하고 내역 보기 권한이 있는지 확인해야 하는 경우 여기에는 많은 기능적 책임이 포함되며 이러한 기능은 서로 종속되지 않습니다. 아마도 허가 처리와 환율은 서로 다른 구성요소여야 할 것입니다. 반면 정수부, 소수부, 통화 표시부 등 여러 구성요소가 있고 프로그래머가 잔액을 표시하려면 조립할 구성요소를 모두 찾아야 합니다. 문제는 응집력이 높은 구성 요소를 만드는 것입니다.

Building Components

구성요소를 만드는 방법에는 여러 가지가 있습니다. 우리는 구성 요소를 합리적인 범위 내에서 재사용할 수 있기를 원합니다. 또한 우리는 더 큰 구성 요소 내에서 사용할 수 있는 작은 구성 요소를 만들고 싶습니다. 이상적으로 우리는 시스템을 더 쉽게 관리하고 확장할 수 있도록 느슨하게 결합되고 고도로 집계된 구성 요소를 구축하려고 합니다. React 컴포넌트의 Prop은 함수의 매개변수와 유사하며 상태 비저장 함수를 갖는 컴포넌트로 간주될 수도 있습니다. 컴포넌트에서 props를 어떻게 정의하는지, 컴포넌트를 어떻게 재사용할 수 있는지 생각해 볼 필요가 있습니다.

다음으로 비용 관리 시스템을 배경으로 비용의 세부 형식을 분석하고 구성 요소 구축 방법을 소개합니다.

type Expense {
      description: string
      category: string
      amount: number
      doneAt: moment
    }

모델에 따르면 비용 형식에 대한 프로그램 모델링 방법은 다음과 같습니다.

  • 소품 없음

  • 비용 객체 전달

  • 필요한 속성 전달

  • 모든 속성의 맵 전달

  • 형식화된 하위 객체 전달

다음은 논의된다 위의 배송 방법을 별도로 사용하면 장단점이 있습니다. 그러나 사용 시나리오 및 종속 시스템에 따라 위 방법 중 하나를 사용하는 경우 항상 주의를 기울여야 합니다. 그것이 우리도 하는 일입니다. 적절하게 추상적인 장면을 구축하는 것입니다.

No props

이것은 정적 데이터를 쓰는 구성 요소를 구축하는 가장 간단한 솔루션입니다.

const ExpenseDetails = () => (
      <p className=&#39;expense-details&#39;>
         <p>Category: <span>Food</span></p>
         <p>Description: <span>Lunch</span></p>
         <p>Amount: <span>10.15</span></p>
         <p>Date: <span>2017-10-12</span></p>
      </p>
    )

props를 전달하지 않으면 유연성이 제공되지 않으며 구성 요소는 단일 장면에서만 사용할 수 있습니다. 비용 세부사항 예시에서 우리는 처음에 컴포넌트가 일부 props를 받아들여야 한다는 것을 알 수 있습니다. 그러나 일부 시나리오에서는 소품을 사용하지 않는 것도 좋은 해결책입니다. 첫째, 상표, 로고, 회사 정보 등 쉽게 변경할 수 없는 콘텐츠가 포함된 소품이 포함된 일부 구성 요소를 사용할 수 있습니다.

const Logo = () => (
      <p className=&#39;logo&#39;>
       <img src=&#39;/logo.png&#39; alt=&#39;DayOne logo&#39;/>
      </p>
    )

컴포넌트를 가능한 한 작게 작성하면 시스템 유지 관리가 더 쉬워집니다. 정보를 한 곳에 보관하고 한 곳에서만 수정하면 됩니다. 여러 곳에 중복된 코드를 작성하지 마세요.

비용 개체 전달

비용 세부 정보가 결정되면 데이터를 구성 요소에 전달해야 합니다. 먼저 비용 개체를 전달해야 합니다.

const ExpenseDetails = ({ expense }) => (
      <p className=&#39;expense-details&#39;>
         <p>Category: <span>{expense.category}</span></p>
         <p>Description: <span>{expense.description}</span></p>
         <p>Amount: <span>{expense.amount}</span></p>
         <p>Date: <span>{expense.doneAt}</span></p>
      </p>
    )

비용 개체를 비용 세부 정보 구성 요소에 전달하는 것이 합리적입니다. 비용 세부 정보 형식은 일관성이 뛰어나며 비용 데이터를 표시합니다. 형식을 변경해야 할 때마다 여기에서만 수정할 수 있습니다. 비용 세부 정보의 형식을 변경해도 비용 개체 자체에는 부작용이 없습니다.

이 구성 요소는 비용 개체와 밀접하게 연결되어 있습니다. 이것이 나쁜 것입니까? 물론 그렇지 않습니다. 그러나 이것이 우리 시스템에 어떤 영향을 미치는지 알아야 합니다. 객체를 소품으로 전달하면 비용 세부 정보 구성 요소는 비용 내부 구조에 의존합니다. 비용의 내부 구조를 변경하면 비용 세부 구성 요소도 변경해야 합니다. 물론 한 곳에서만 수정하면 됩니다.

이 디자인은 향후 변화에 어떻게 적응하나요? 필드를 추가, 변경 또는 삭제하는 경우 구성 요소 하나만 변경하면 됩니다. 다른 형식의 달력 디스플레이를 추가해야 하면 어떻게 됩니까? 달력 서식을 위한 새로운 소품을 추가할 수 있습니다.

rreee

我们开始增加属性来使组件更加灵活。如果只有几个选项,那么一切都是很ok的。系统业务开始扩展后问题就来了,在不同的场景下我们需要维护大量的props。

const ExpenseDetails = ({ expense, dateFormat, withCurrency, currencyFormat, isOverdue, isPaid ... })

 

增加props可以使得组件重用性更好,但你可能设计了多重功能职责的组件。这种规则也同样在函数写法中运用。可以用多个参数来创建一个函数,当参数的数目超过3个或者4个时候,意味着这个函数在做很多事情了,也许这时候应该将函数拆成更小的函数来的更加简单。

随着组件props的增加,我们将其拆分成定义明确的组件,比如:OverdueExpenseDetails, PaidExpenseDetails等。

只传递必要的属性

为了减少对象自身的内容,我们可以只传递必要的属性值。

const ExpenseDetails = ({ category, description, amount, date }) => (
      <p className=&#39;expense-details&#39;>
         <p>Category: <span>{category}</span></p>
         <p>Description: <span>{description}</span></p>
         <p>Amount: <span>{amount}</span></p>
         <p>Date: <span>{date}</span></p>
      </p>
    )

 

我们分别传递属性,这样我们将一部分工作责任转移给了组件使用者。如果费用的内部结构发生变化,他将不会影响费用明细的格式化。但可能影响每个使用组件的地方,因为我们可能需要修改props。当我们以独立的属性传递props时候,一个组件将更加抽象了。

只传递需要的字段对未来设计改动是如何影响的?增加、更新或者删除字段将不会很容易。无论何时我们要增加一个字段,我们不仅仅要改变费用细节的实现,也需要改变每个使用组件的地方。另外一个方面,支持多种日历格式化几乎是现成的,我们可以传递日历作为prop,也可以传递格式化后的日历。

<ExpenseDetails 
      category={expense.category} 
      description={expense.description}
      amount={expense.amount}
      date={expense.doneAt.format(&#39;YYYY-MM-DD&#39;)}
    />

 

决定如何展示特定的字段应该在掌握在具体使用组件的人手中,这将不是费用明细组件关心的内容。

传递map或者array的属性

为了达到组件抽象化,我们可以传递一个map的属性值。

const ExpenseDetails = ({ expense }) => (
      <p class=&#39;expense-details&#39;>
      {
        _.reduce(expense, (acc, value, key) => {
          acc.push(<p>{key}<span>{value}</span></p>)
        }, [])
      }
      </p>
    )

 

使用组件的人控制费用明细的格式化,传递给组件的对象格式则必须正确。

const expense = {
      "Category": "Food",
      "Description": "Lunch",
      "Amount": 10.15,
      "Date": 2017-10-12
    }

 

这个方案有很多缺陷,我们很难控制组件展示的样式,并且展示顺序也没有指定。因此,如果我们需要某种顺序的话,可以采用array代替map来解决这个问题。但是仍然还有缺陷。

传递map 和array作为props 不与费用耦合,也根本与它不一致。增加和删除新属性虽然只改变了prop,但是我们无法控制组件本身的格式。如果我们只改变类别的格式化,这不是一个可行的办法。(确切地说,总有一个办法来解决,例如,传递另外一个格式化后的props。这个解决方案似乎不再简单了。)

传递一个格式化的子对象

我们也可以只通过直接传对一个子对象,这样就能考虑更少的组件内需要如何展示。

const ExpenseDetails = ({ children }) => (
      <p class=&#39;expense-details&#39;>
        { children }
      </p>
    )

 

在这种情况下,费用明细只是一个提供结构和样式的容器。展示所有信息则是使用组件的人必须提供的。

<ExpenseDetails>
      <p>Category: <span>{expense.category}</span></p>
      <p>Description: <span>{expense.description}</span></p>
      <p>Amount: <span>{expense.amount}</span></p>
      <p>Date: <span>{expense.doneAt}</span></p>
    </ExpenseDetails>

 

在费用明细这个案例中,我们需要重复许多工作,因此这也许不是一个好的解决方案。尽管如此,灵活性则是巨大的,因为有可能有很多不同的格式化操作。增删改只需要改变使用组件时候传入的值。日期格式也是一样的,我们虽然失去了功能内聚的特点,但这也是我们不得不付出的代价。

环境为王

正如你所看到,我们讨论了它们的不同优缺点和可能性。哪一个最好呢,这取决于:

  • 项目本身

  • 项目阶段

  • 组件自身,需要很多特殊的组件组成还是只需要简单的一些选项值

  • 自己的习惯

  • 使用环境-适合频繁的改变和被多次使用

没有一个万能的解决方案,一个方案也并不能适用所有场景。我们如何构建组件对于系统的维护和系统可扩展方面有着深远的影响。这完全依赖于组件所使用的环境。非常幸运的是,我们有很多可使用的方案。组件是功能的抽象集合,它既能构建小系统也能构建大系统。所以这仅仅只是一个选择问题。

相关推荐:

store优化React组件的方法详解

如何在React组件“外”使用父组件的Props

React组件的生命周期函数是什么

위 내용은 React 컴포넌트를 구축하는 가장 완벽한 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.