React组件模式是什么

2023-05-24,,

这篇文章给大家分享的是有关React组件模式是什么的内容。小编觉得挺实用的,因此分享给大家做个参考。一起跟随小编过来看看吧。

组件是 React 的核心,因此了解如何利用它们对于创建优秀的设计结构至关重要。

什么是组件

根据 React 官网的介绍,“组件让你可以将 UI 分割成独立的、可重用的部分,并独立管理每个部分。”

当你第一次安装 npm install react 时,会得到一件事:组件及其 API。与 JavaScript 函数类似,组件接受名为 “props” 的输入并返回 React 元素,该元素描述(声明)用户界面(UI)的外观。这就是为什么 React 被称为声明性 API,因为你告诉它你希望 UI 是什么样子的,而 React 负责其余的工作。

可以把声明式想像成当打的去一个目的

地时,只需要告诉司机去哪里,他就会开车把你送到那里。命令式编程正好相反—,你得自己驾车到那里。

组件的 API

当安装 React 后,便可以使用 React 提供的 API,基本可以分成 5 种。

  • render

  • state

  • props

  • context

  • lifecycle events

尽管一个组件可以使用上述所有 API,但一个组件通常用到只有少数几个 API,而其他组件则只使用其他 API。

可以对组件使用不同的 API 对组件进行划分,分为 有状态(stateful)无状态(stateless) 两种组件。

  • 有状态组件通常使用 API: render, state 和生命周期相关事件。

  • 无状态组件通常使用 API: render, props 和 context。

以上就是我们为佬要介绍 组件模式 的原因。组件模式是使用 React 时的最佳实践,最初引入组件模式是为了将数据逻辑和 UI 表现层进行分离。通过在组件之间划分职责,您以创建更多可重用的、内聚的组件,这些组件可用于组合复杂的 UI,这在构建可扩展的应用程序时尤其重要。

组件模式

通常组件模式有以下几种:

  • Container (容器组件)

  • Presentational (展示组件)

  • Higher order components (高级组件)

  • Render callback (渲染回调)

Container (容器组件)

“容器组件就是取数据,然后渲染子组件而已” —— Jason Bonta

容器组件是你的数据或逻辑层并利用 stateful API,使用生命周期事件,你可以连接 state 到
redux 或者 Flux 的 storage 中,并将数据和回调作为  props 传递给子组件。

在容器组件的 render 方法中,你可以使用 展示组件 来渲染具体的样式。为了能够访问到所有状态 API,容器组件必须使用 class 的方式声明,而不是使用函数式方法声明。

在下面的示例中,我们有一个名为 Greeting 的类组件,它具有状态,生命周期事件componentDidMount() 和 render 方法。

class Greeting extends React.Component {
  constructor() {
    super();
    this.state = {
      name: "",
    };
  }

  componentDidMount() {
    // AJAX
    this.setState(() => {
      return {
        name: "William",
      };
    });
  }

  render() {
    return (
      <div>
        <h2>Hello! {this.state.name}</h2>
      </div>
    );
  }
}

此时,该组件是一个有状态类组件,为了使 Greeting 成为一个容器组件,我们可以将 UI 拆分为一个 展示组件,将在下面进行说明。

展示组件

展示组件 使用 props、render 和 context (无状态API),并且由于不需要使用生命周期相关 Api,可以使用纯函数来简化表述它们:

const GreetingCard = (props) => {
  return (
    <div>
      <h2>Hello! {props.name}</h2>
    </div>
  )
}

展示组件 仅从 props 接收数据和回调,这些数据和回调可以由其容器组件(父组件)提供。

容器组件和展示组件各自将数据/逻辑和展示部分封装到各自的组件中:

const GreetingCard = (props) => {
  return (
    <div>
      <h2>{props.name}</h2>
    </div>
  )
}

class Greeting extends React.Component {
  constructor() {
    super();
    this.state = {
      name: "",
    };
  }

  componentDidMount() {
    // AJAX
    this.setState(() => {
      return {
        name: "William",
      };
    });
  }

  render() {
    return (
      <div>
       <GreetingCard name={this.state.name} />
      </div>
    );
  }
}

如你所见,已经将 Greeting 组件中展示相关的部分移动到了它自己的函数式展示组件中。当然,这是一个非常简单的例子——对于更复杂的应用程序,这也是最基本的。

高阶组件

高阶组件是一种函数,它接受一个组件作为参数,然后返回一个新的组件。

这是一种可以对输入组件的 props 进行修改(增删改查)然后返回全新的修改后的组件强大模式,想想 react-router-v4 和 redux 。用了 react-router-v4 后,你可以使用 withRouter() 来继承以 props 形式传递给组件的各种方法。同样,用了redux,就可以使用 connect({})() 方法来将展示组件和 store 中的数据进行连接。

代码演示:

import {withRouter} from 'react-router-dom';
class App extends React.Component {
  constructor() {
    super();
    this.state = {path: ''}
  }
  
  componentDidMount() {
    let pathName = this.props.location.pathname;
    this.setState(() => {
      return {
        path: pathName,
      }
    })
  }
  
  render() {
    return (
      <div>
        <h2>Hi! I'm being rendered at: {this.state.path}</h2>
      </div>
    )
  }
}

export default withRouter(App);

导出组件时,使用用 react-router-v4 的 withRouter()方法封装它。 在 组件 App 的生命周期事件 componentDidMount() 方法中,我们使用this.props.location.pathname 提供的值来更新 state。 由于我们使用了 withRouter 高阶组件,我们可以直接访问 this.props.locationlocation,而不需要直接将 location 作为 props 直接传入,非常方便。

渲染回调

与高阶组件类似,渲染回调或渲染 props 被用于共享或重用组件逻辑。虽然许多开发人员倾向于使用 高阶组件 的可重用逻辑,但是使用 渲染回调 仍然有一些非常好的理由和优势——这是在 Michael Jackson 的“永不写另一个高阶组件”中得到了最好的解释。简而言之,渲染回调减少了命名空间冲突,并更好的说明了逻辑来源。

class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
    };
  }

  increment = () => {
    this.setState(prevState => {
      return {
        count: prevState.count + 1,
      };
    });
  };

  render() {
    return (
      <div onClick={this.increment}>{this.props.children(this.state)}</div>
    );
  }
}

class App extends React.Component {
  render() {
    return (
      <Counter>
        {state => (
          <div>
            <h2>The count is: {state.count}</h2>
          </div>
        )}
      </Counter>
    );
  }
}

在 Counter 类中,在 render 方法中嵌入 this.props.children 并将 this.state 作为参数。在 App 类中,我们可以将我们组件封装在 Counter 组件中,因此我可以操作 Counter 组件内的逻辑。

Counter 组件的本质是暴露了 children 这个外部属性,将 children 具体的渲染细节交个 Counter 的使用者,使用的时候只需要将组件传入到 Counter 的 children 中,当然可以使用其他参数,如果 children 不够的话。

代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug。

感谢各位的阅读!关于React组件模式是什么就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到吧!

《React组件模式是什么.doc》

下载本文的Word格式文档,以方便收藏与打印。