React的组件模式

Posted chargo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React的组件模式相关的知识,希望对你有一定的参考价值。

组件化开发是React的核心,学会如何利用和组织他们有助于你创建良好的设计结构。

什么是组件?

根据react官网的解释大致如下:

组件可以独立的拆分你的UI试图,他们是可以复用的,独立的单元。

和函数类似,React中组件接收的输入源称为props,并且返回react元素。react元素是对UI界面的描述。你可以告诉react你期望的UI界面,剩下的工作可以交给react来处理。

我们拿乘坐计程车打比方,当你告诉司机你想要去的地方,司机就会按照你期望地点将你安全的送到目的地。而不用你自己亲自开车。

Component Api‘s

react的api有哪些呢?react总共有主要的5大api他们分别是:

1.render

2.state

3.props

4.context

5.life cycle events

组件有状态组件和无状态组件,状态组件使用可控制状态的api,render state 和life cycle events。无状态组件使用render props context。

组件设计模式,可以将你的数据层和逻辑层分开,通过职责区分你的组件。你可以创建可以复用的组件,而这些组件又可以创建出更加复杂的UI试图。这对于构建app是极为重要的。

在组件设计模式中我们可以将组件分为:

1.容器组件

2.展示型组件

3.高阶组件

4.render回调

容器组件:

容器组件用于获取数据,渲染他下面的子组件,这个就是容器组件。

容器组件可以是你的数据层或者业务逻辑层,并且使用的是stateful api。通过生命周期函数你可以连接你的状态管理库,例如redux或者flux。容器组件可以传递数据和回调函数给子组件。在容器组件的render方法中,通过展示组件的组合来构建你的UI试图。因为容器组件是具有状态的,所以你需要使用class来声明你的组件,而不是使用函数式组件。

在如下例子中,有个class component名为Greeting,他有state,生命周期函数和render函数。

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

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

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

这个组件是具备状态的class组件。为了让Greeting组件成为容器型组件,我们需要把UI拆分到展示型组件中。如下:

展示型组件:

展示型组件利用的是,props,render,context(stateless api‘s)

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

容器组件通过props传递数据和回调函数给展示型组件。通过容器组件和展示型组件来共同封装业务逻辑,并组合成新的组件。

const GreetingCard = (props) => {
  return (
    <div>
      <h1>{props.name}</h1>
    </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>
    );
  }
}

如上示例,我们移除了标签元素,并且将他放入了无状态的展示型组件中。当然这个只是这个很简单的示例,但是在复杂的app运用中,原理都是相同的。

高阶组件:

高阶组件,是以组件作为参数,并且返回一个新的组件。

高阶组件可以提供数据给任意数量的组件,并且有效的复用业务逻辑。它是个强大的模式。例如在react-router和redux中,在react-router中你可以使用widthRouter()去继承方法,并且通过props传递给你的组件。在redux中你可以connect方法去传递你的actions。

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>
        <h1>Hi! I‘m being rendered at: {this.state.path}</h1>
      </div>
    )
  }
}

export default withRouter(App);

如上示例,我们通过this.props.location.pathname来更新状态。通过withRouter方法来包裹组件。现在我们的组件可以通过props来出来react-rouoter的方法this.props.location.pathname;

 

Render callbacks

类似于高阶组件,render callbacks或者render props都是用来复用组价逻辑的。当更多的开发者倾向于高阶组件来复用业务逻辑的时候,这里有几个原因和优点可以让你尝试下使用render callbacks。render callsbacks可以有效的减少命名冲突,并且清晰的展示逻辑的来源。

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>
            <h1>The count is: {state.count}</h1>
          </div>
        )}
      </Counter>
    );
  }
}

在Counter类的render方法中,内嵌了this.props.children并且以this.state作为参数传入。再App类中我们可以再Counter中包裹我们的组件来处理Counter的逻辑。因此他可以处理来自Counter中的state。

以上是关于React的组件模式的主要内容,如果未能解决你的问题,请参考以下文章

React 函数组件与class组件的区别

已解决在react+ts中 atnd 用 upload 组件报错Failed to execute ‘readAsArrayBuffer,param 1 is notof type Blob(代码片段

已解决在react+ts中 atnd 用 upload 组件报错Failed to execute ‘readAsArrayBuffer,param 1 is notof type Blob(代码片段

[译] 如何在React中写出更优秀的代码

是否有用于 React Function 组件的类型,包括返回片段、空值、字符串等?

react-router-relay 是不是与 Relay 模式不一致?