您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

React 组件

React 组件

组件允许你将 UI 拆分为独立可复用的片段,并对每个片段进行独立构思。本指南旨在介绍组件的相关理念。

组件,从概念上类似于 JavaScript 。它接受任意的入参(即 “props”),并返回用于描述展示的 React 元素。

React 应用就是构建在 React 组件之上的。

组件有两个核心概念:

props

state

组件就是通过这两个的值在 render 里面这个组件对应的 HTML 结构。

注意:组件的 HTML 结构只能有单一的根节点。

组件与 class 组件

定义组件最简单的方式就是编写 JavaScript :

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

该是有效的 React 组件,因为它接收唯一带有数据的 “props”(代表)对象与并返回 React 元素。这类组件被称为“组件”,因为它本质上就是 JavaScript 。

你同时还可以使用  来定义组件:

class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

上述两个组件在 React 里是等效的。

渲染组件

之前,我们遇到的 React 元素都只是 DOM :

const element = <div />;

不过,React 元素也可以是的组件:

const element = <Welcome name="" />;

当 React 元素为组件时,它会将 JSX 所接收的(attributes)转换为单个对象传递给组件,这个对象被称之为 “props”。

例如,这段会在上渲染 “Hello, ”:

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

const element = <Welcome name="" />;
ReactDOM.render(
  element,
  document.getElementById('root')
);

让我们来回顾一下这个例子中发生了什么:

我们 ReactDOM.render() ,并传入 <Welcome name="" /> 作为参数。

React  Welcome 组件,并将 {name: ''} 作为 props 传入。

Welcome 组件将 <h1>Hello, </h1> 元素作为返回值。

React DOM 将 DOM 高效地更新为 <h1>Hello, </h1>。

注意: 组件必须以大写字母开头。

React 会将以小写字母开头的组件视为原生 DOM 。例如,<div /> 代表 HTML 的 div ,而 <Welcome /> 则代表组件,并且需在作用域内使用 Welcome。

你可以在深入 JSX中了解更多关于此规范的原因。

划分状态数据

一条原则:让组件尽可能地少状态。

这样组件逻辑就越容易维护。

什么样的数据可以当作状态?

当更改这个状态(数据)需要更新组件 UI 的就可以认为是 state,下面这些可以认为不是状态:

可计算的数据:比如数组的长度

和 props 重复的数据:除非这个数据是变更的

最后回过头来反复看几遍 ,相信会对组件有更深刻的认识。

无状态组件

你也可以用纯粹的来定义无状态的组件(stateless function),这种组件没有状态,没有生命周期,只是简单的接受 props 渲染 DOM 结构。无状态组件非常简单,开销很低,如果可能的话尽量使用无状态组件。比如使用箭头定义:

const HelloMessage = (props) => <div> Hello {props.name}</div>;
render(<HelloMessage name="John" />, mountNode);

因为无状态组件只是,所以它没有实例返回,这点在想用 refs 无状态组件的时候要注意,参见。

组件生命周期

一般来说,组件类由 extends Component 创建,并且提供 render 以及其他可选的生命周期、组件相关的事件或来定义。

简单的例子:

import React, { Component } from 'react';
import { render } from 'react-dom';

class LikeButton extends Component {
  constructor(props) {
    super(props);
    this.state = { liked: false };
  }

  handleClick(e) {
    this.setState({ liked: !this.state.liked });
  }

  render() {
    const text = this.state.liked ? 'like' : 'haven\'t liked';
    return (
      <p onClick={this.handleClick.bind(this)}>
          You {text} this. Click to toggle.
      </p>
    );
  }
}

render(
    <LikeButton />,
    document.getElementById('example')
);

getInitialState

初始化 this.state 的值,只在组件装载之前一次。

如果是使用 ES6 的语法,你也可以在构造中初始化状态,比如:

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

  render() {
    // ...
  }
}

getDefaultProps

只在组件创建时一次并缓存返回的对象(即在 React.createClass 之后就会)。

因为这个在实例初始化之前,所以个里面不能依赖 this 到这个组件的实例。

在组件装载之后,这个缓存的结果会用来保证访问 this.props 的时,当这个没有在父组件中传入(个组件的 JSX 里设置),也总是有值的。

如果是使用 ES6 语法,可以直接定义 defaultProps 这个类来替代,这样能更直观的知道 default props 是预先定义好的对象值:

Counter.defaultProps = { initialCount: 0 };

render

必须组装这个组件的 HTML 结构(使用原生 HTML 或者子组件),也可以返回 null 或者 false,这时候 ReactDOM.findDOMNode(this) 会返回 null。

生命周期

componentWillMount

只会在装载之前一次,在 render 之前,你可以个里面 setState 改变状态,并且不会导致额外一次 render

componentDidMount

只会在装载完成之后一次,在 render 之后,从这里开始可以通过 ReactDOM.findDOMNode(this)到组件的 DOM 节点。

这些不会在首次 render 组件的周期

componentWillReceiveProps

shouldComponentUpdate

componentWillUpdate

componentDidUpdate

componentWillUnmount

更多关于组件相关的说明,参见:


联系我
置顶