美文网首页
React组件介绍

React组件介绍

作者: Shaw007 | 来源:发表于2019-01-08 23:56 被阅读0次

组件介绍

React中组件主要可分为函数组件和类组件,两者区别是函数组件没有state和生命周期,故函数组件也称为 stateless functional components, 适用于仅进行简单渲染操作的组件。
此外,还有高阶组件HOC(higher-order component), 即高阶函数,接收一个React组件作为参数,然后返回另外的React组件,通常是原组件的加强版。

函数组件

可接收props,返回一个JSX元素,例如

function ReactHeader(props) {
  return <h1>React {props.version} Documentation</h1>
}

<ReactHeader version={18}></ReactHeader>

经过Babel转义后为

function ReactHeader(props) {
  return React.createElement(
    "h1",
    null,
    "React ",
    props.version,
    " Documentation"
  );
}

React.createElement(ReactHeader, { version: 18 });
函数组件参数初始化
  1. 在函数组件上添加一个名为defaultProps的静态属性
function ThemedButton(props) {
  const { theme, label, ...restProps } = props;
  return <button className={`btn btn-${theme}`} {...restProps}>{ label }</button>
}

// 设置默认属性
ThemedButton.defaultProps = {
  theme: "secondary",
  label: "Button Text"
};
  1. 使用ES6的对象解构语法
// METHOD 1:
function ThemedButton(props) {
  const { theme = 'secondary', label = 'Button Text', ...restProps } = props;
  return <button className={`btn btn-${theme}`} {...restProps}>{ label }</button>
}

// METHOD 2:
// 更加紧凑的方式
function ThemedButton({ theme = 'secondary', label = 'Button Text', ...restProps }) {
  return <button className={`btn btn-${theme}`} {...restProps}>{ label }</button>
}

类组件

可以使用ES6的extends写法,15.4之前可利用React.creatClass创建类组件,但如今已经弃用了。
关于两者区别可参考这里
考虑到props是不建议修改的,React推荐数据源从上往下流,仅有一个被trusted的数据源,其余由dispatch发送事件,subscribe订阅事件, store存储所有信息,该思想为flux。为了追踪一些状态或变量,React在class中提供了state对象,用于存储组件私有变量,对state的改变则通过setState进行

示例:

class simple extends React.Component {
  constructor(){
    super(props)
    this.state = {
        status: ''
    }
  }
  render() {
    return (
      <h1>Simple test</h1>
    )
  }
}
console.log(<simple />); 

经过Babel转义后

var simple = function (_React$Component) {
  _inherits(simple, _React$Component);

  function simple() {
    _classCallCheck(this, simple);

    var _this = _possibleConstructorReturn(this, (simple.__proto__ || Object.getPrototypeOf(simple)).call(this, props));

    _this.state = {
      status: ''
    };
    return _this;
  }

  _createClass(simple, [{
    key: 'render',
    value: function render() {
      return React.createElement(
        'h1',
        null,
        'Simple test'
      );
    }
  }]);

  return simple;
}(React.Component);

console.log(React.createElement('simple', null));
类组件初始化

类组件的初始化也可在组件上添加一个名为defaultProps的静态属性, 定义一个名为Component的组件后

Component.defaultProps = {
  name: "admin",
  age: 20
};

或者

//在组件内设置(与constructor平级)
static defaultProps = {
    name: 'com',
    age: 18
  }
组件参数类型检测

组件的类型检测需要额外引入prop-types

  <script src="./prop-types.js"></script>

然后在组件上应用propTypes

Component.propTypes = {
  name: PropTypes.string,
  age: PropTypes.number    
}

关于类型检测更多种类可参考这里

组件this绑定

与ES6中类语言一致,通过extends得到的class,组件内的方法将不会自动将this绑定到实例上,有三种方式可以进行绑定

实例:

constructor(props){
    super(props)
    this.state = {
      status: 'logged',
      message: ''
    }
    this.handleChange = this.handleChange.bind(this)
  }
  handleChange(e){
    console.log('handle Change')
    console.log(this); // 在constructor中通过bind绑定
    this.setState({message:e.target.value})
    console.log(this.state.message)
  }
  handleFocus(){  
      console.log('handle Focus')
      console.log(this); // 在render的时候通过bind绑定
  }
  handleBlur = ()=>{  
      console.log('handle Blur')
      console.log(this); // 用箭头函数自动绑定
  }
  render(){
    console.log(this.props)
    return (
      //写style是需要加双括号,JSX编码格式要求,style必须是一个对象
      <div style={{color:"blue"}}>我是Component组件 &gt;&gt; {undefined}
        <p>{this.props.children}</p>
        <p>Name: {this.props.name}</p>
        <p>Age: {this.props.age}</p>
        <p>Status: {this.state.status}</p>
        <p>Message: {this.state.message}</p>
        <input type="text" value={this.state.message} onChange={this.handleChange} 
                              onFocus={this.handleFocus.bind(this)}  
                              //第一、三种写法的性能一样,在实例化时会调用
                              //但万一我们需要改变语法结构,第一种方式可以完全不需要去改动 JSX 的部分:
                              //第二种则会在触发render时不断进行调用,性能不太好
                              onBlur={this.handleBlur}/>
      </div>
    )
  }

另外可通过以下方式,将函数组件转为类组件
a. 通过class 声明与函数同名的类,该类继承React.Component
b. 添加一个空方法,名为render
c. 将函数主体移入render方法中
d. 将render中的props替换为this.props
e. 将props中需要修改的data移入state中
f. 在类的render中,将this.props.data替换为this.state.data
g. 创建一个class constructor 用于初始化this.state

类组件生命周期

React类组件生命周期有较大的变动,我写这篇文章的时候是V16.7,V16.3开始官方已经申明以下生命周期函数会在下一个大版本停用,为了兼容性,在这些过时的生命周期函数前加前缀UNSAFE__

  1. componentWillMount
  2. componentWillReceiveProps
  3. componentWillUpdate
    取而代之的
  4. static getDerivedStateFromProps
    取代componentWillReceiveProps
    特点是纯函数,且由于是静态方法故无法获取this
  5. getSnapshotBeforeUpdate
    可取代componentWillUpdate
    官方提出改动一是WillMount争议较大,可参见这里存在滥用情况多,去除后两个是为了以后增加异步渲染的过程。

有一种错觉,在componentWillMount请求的数据在render就能拿到,但其实render在willMount之后几乎是马上就被调用,根本等不到数据回来,同样需要render一次“加载中”的空数据状态,所以在didMount去取数据几乎不会产生影响。另外,react只能保证componentDidMount-componentWillUnmount成对出现,componentWillMount可以被打断或调用多次,因此无法保证事件监听能在unmount的时候被成功卸载,可能会引起内存泄露

以下是新旧生命周期示意图对比
[图片上传中...(React_lifecycle_old.png-b3c3f5-1546961611183-0)]

[图片上传中...(React_lifecycle_new.png-68ca8-1546961671751-0)]

建议用法:

  1. constructor初始化state
  2. componentDidMount
    此过程请求异步加载的数据
    并添加事件监听
  3. getDerivedStateFromProps(nextProps,preState)

根据props更新之前的state,若需要在Setstate前进行对比props是否有更新,需在shouldComponentUpdate中使用

if (nextProps.currentRow !== prevState.lastRow) {
  return {
    ...
    lastRow: nextProps.currentRow,
  };
  // 不更新state
  return null
}
  1. componentDidUpdate
    处理由state或props更新触发的请求

  2. getDerivedStateFromProps
    传入新的props重新异步读取数据

  static getDerivedStateFromProps(nextProps, prevState) {
    // Store prevId in state so we can compare when props change.
    if (nextProps.id !== prevState.prevId) {
      return {
        externalData: null,
        prevId: nextProps.id,
      };
    }
    // No state update necessary
    return null;
  }
  componentDidUpdate(prevProps, prevState) {
    if (this.state.externalData === null) {
      this._loadAsyncData(this.props.id);
    }
  }

参考部分1
[参考部分2]

相关文章

  • React基础

    react 教程 react 组件介绍 react state 介绍 react Props 介绍 React:组...

  • React概念

    介绍 React的核心思想是:封装组件。React大体包含下面概念: 组件React 应用都是构建在组件之上。上面...

  • React组件名大小写

    React组件介绍 React中,组件是可分为函数组件和类组件,不管哪种方式定义的组件,其组件名都必须是大写 大小...

  • React_组建

    这次我们来学习React中的组件。组件是React的核心。 根据React官网的介绍,组件可以将UI切分成一些独立...

  • 第9节 React中的父子组件及传值2019-05-26

    一、React组件介绍 1.1React中的组件 解决html 标签构建应用的不足。 1.2使用组件的好处 把公共...

  • React 组件介绍

    https://easykotlin.quora.com/Components-the-war-horses-of...

  • React组件介绍

    组件介绍 React中组件主要可分为函数组件和类组件,两者区别是函数组件没有state和生命周期,故函数组件也称为...

  • 最强React精讲教程+源码,资源地址⬇️

    React_模块化,组件化介绍.avi React_hello React.avi React_虚拟DOM对象, ...

  • React基础

    React包含react元素和react组件 react元素 react组件 react组件分为函数组件和类组件 ...

  • 从高阶函数到高阶组件

    介绍 高阶组件(HOC)是 React 中用于复用组件逻辑的一种高级技巧。HOC 自身不是 React API 的...

网友评论

      本文标题:React组件介绍

      本文链接:https://www.haomeiwen.com/subject/wjgbrqtx.html