React 实践:第三方方法调用类库的改造

Author Avatar
Splendour 1月 07, 2017

我们知道,React 组件的常规渲染是根据传入的 props 来改变的,但有时候,我们会需要使用一些第三方库,它们提供了一些方法来操作 dom (新增或修改)以改变页面展示,这时候就需要我们做一次转化,使之能符合 React 的常规做法。下面就以 Ant-designmessage 方法为例,介绍一下改造的实践过程。

message 的调用方法

根据文档的介绍,使用 message 方法产生一个全局 loading 的代码如下

const hide = message.loading('Action in progress..', 0);
// Dismiss manually and asynchronously
setTimeout(hide, 2500);

非常简单,而我们不想在 React 逻辑代码中写类似的方法调用,只想通过 action 改变 store 的状态,来显示和隐藏这个 loading

定义Loading 组件

首先,我们希望组件接受两个属性,show 代表显示与否,content 代表显示的文本内容

import React, {Component, PropTypes} from 'react';

class Loading extends Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <div />
    );
  }
}

Loading.propTypes = {
  show: PropTypes.bool.isRequired,
  content: PropTypes.string
};

export default Loading;

强制渲染一次

我们是使用第三方库提供的方法来显示和隐藏 loading 内容的,我们就不希望 React 根据 props 来自动渲染组件,以造成不希望出现的现象

shouldComponentUpdate(nextProps, nextState) {
  return false;
}

逻辑实现

既然我们限制了组件只渲染一次,那我们应该在哪里去进行方法调用呢?我们是希望根据 props 来改变,所以答案很简单:componentWillReceiveProps

componentWillReceiveProps(nextProps) {
  if (nextProps.show) {
    this.hide = message.loading(nextProps.content || 'loading', 0);
  } else {
    this.hide && this.hide();
  }
}

其中,hide 方法是 Ant-design 提供的隐藏该 loading 的方法,我们在 show = false 的时候,执行该方法即可实现 loading 的隐藏。最后,我们再添加 this.hide 的初始化

constructor(props) {
  super(props);
  this.hide = () => {};
}

总结

我们实现的 Loading 组件整体代码如下

import React, {Component, PropTypes} from 'react';

import {message} from 'antd';

class Loading extends Component {
  constructor(props) {
    super(props);
    this.hide = () => {};
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps.show) {
      this.hide = message.loading(nextProps.content || 'loading', 0);
    } else {
      this.hide && this.hide();
    }
  }

  shouldComponentUpdate(nextProps, nextState) {
    return false;
  }

  render() {
    return (
      <div />
    );
  }
}

Loading.propTypes = {
  show: PropTypes.bool.isRequired,
  content: PropTypes.string
};

export default Loading;

只需要把组件在页面最上层引入,并且传入 store 中的 show content 两个值即可,思路清晰,也使得 React 代码变得更加纯粹和可读了