组件和属性

组件,react 里的组件分三类,原生组件和自定义组件还有点组件

这里的原生组件是带着引号的,原因是它们不是 html 里的原始组件,而是 React.createElement 创建出来的,但是它有一个规则,就是第一个参数必须是原生 html 标签里有的,比如 div,p 等,除此之外的它找不到就会报错。

自定义组件,就是我们利用函数或 class 创建的自己的组件,首写字母必须大写,这样是为了让 React 好区分是自定义组件还是原生组件

点组件就是 React 内置的组件,比如<React.Provider>等,当然符合该语法都的都可以叫点组件

函数组件

import React from "react";
export default () => {
  return (
    <div>
      <p>函数组件必须要一个return</p>
    </div>
  );
};
1
2
3
4
5
6
7
8

优点:执行速度快,不占内存,因为没有实例化对象 缺点:在不使用 hook 的情况下,没有生命周期等高级方法 适用于:做 dom 组件、ui 组件 别名:ui 组件、无状态组件

类组件

import React, { Component } from "react";

export default class App extends Component {
  // render函数是必须要有的
  render() {
    return (
      <div>
        <h1>这是一个类组件</h1>
      </div>
    );
  }
}
1
2
3
4
5
6
7
8
9
10
11
12

优点:功能强大,拥有全部 react 特性,有生命周期和状态管理 缺点:相较于函数组件执行慢,因为实例化对象常驻内存所以占用资源 适用于:功能组件,逻辑的存放接口的获取 别名:逻辑组件、类组件、class 组件、功能组件等

属性 props

先来看原生 h5 标签的属性:

  1. 原生属性<a href=''>我是一个链接</a>,a 标签上的 href 就是原生属性
  2. 自定义属性<img data-src=''/>,img 的 data-src 就是自定义属性

原生 VS 自定义:原生属性只能做浏览器原生支持的功能,自定义属性一般用来传参或状态变化

props 的概念,可以追溯到原生 js 时代,比如,一个盒子点击放大,再点击缩小。通常我们是在元素上绑定一个自定义属性,每次点击的时候就修改这个自定义属性值,每次点击都是通过这个属性值来判断要做的效果。

在 react 里 props 更多用在自定义组件上,那么它的作用也是和上面相同的,所以,我们可以理解是传参。

例子

// Parent.jsx
import React from "react";
import Child from "./Child.jsx";
export default () => {
  return (
    <div>
      <Child name={"给子组件的数据"} />
    </div>
  );
};
// Child.jsx
export default (props) => {
  return <div>这是父组件给我的数据:{props.name}</div>;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14

props 是只读的,对于接收 props 数据的组件来说,props 是不可以被改变的。

修改属性

作为子组件如何修改属性 props 呢?就是调用父级提供修改 props 的方法,让父组件去修改数据

// Parent.jsx
import React from "react";
import Child from "./Child.jsx";
export default class Parent extends React.Component {
  state = {
    name: "给子组件的数据",
  };

  handleChange = (newSrt) => {
    this.setState({
      name: newStr,
    });
  };

  render() {
    return (
      <div>
        <Child name={this.state.name} handle={this.handleChange} />
      </div>
    );
  }
}
// Child.jsx
export default (props) => {
  return (
    <div>
      这是父组件给我的数据:{props.name}
      <button onClick={() => handle("新数据")}>修改父级传入的数据</button>
    </div>
  );
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

通过上面的例子,我们可以看到实际上子组件要修改 props,调用的是父组件传入的函数,借用父组件的函数,我们去修改 props。

同时,我们也发现了上面的示例代码发生了变化,也就是父组件用的 class 组件,是因为函数组件的值修改后,没有办法去更新,它的生命周期只有一次,并且不会更新,所以我们需要用类组件去完成数据发生改变后更新 dom 变化。

children

标签上书写的属性被 props 接受,但是插入到组件内的元素则被 props.children 接受

<Siv></Siv>
1
Last Updated:
Contributors: websong