ES6 + React组件实例方法

我在React中制作了一个小的Video组件(因为你猜对了,正在播放视频),我想将该组件嵌入到父组件中,然后能够在视频组件上调用play方法。

我的视频组件如下所示:

import React, { Component, PropTypes } from 'react';
import ReactDOM from 'react-dom';
const { string, func } = PropTypes;

export default class Video extends Component {

  static propTypes = {
    source: string.isRequired,
    type: string.isRequired,
    className: string
  };

  play = () => {

  };

  render = () => {
    const { className } = this.props;
    return (
      <video className={ className } width="0" height="0" preload="metadata">
        <source src={ this.props.source } type={ this.type } />
        Your browser does not support the video tag.
      </video>
    );
  };
}

这很简单,没有什么奇特的事情在这里发生。

现在在父组件中,我们称它为Page

export default class Page extends Component {
    video = (
        <Video source="some_url" type="video/mp4" />
    );

    render = () => {
        <div onClick={ this.video.play } />
    }
}

但是,如果我登录.play它是未定义的。

接下来,我尝试在Video声明play作为道具,并将默认道具放置如下:

static defaultProps = {
    play: () => {
        const node = ReactDOM.findDOMNode(this);
    }
}

但在这种情况下, this在未定义。

在React ES6类上公开一个函数以便它可以被外部组件调用的正确方法是什么? 我应该附加一些Video.prototype吗?


调用子组件实例方法的正确方法是不要这样做。 :-)

这里有很多资源来讨论为什么,但总结一下:它创建了一个不明确的数据流,它将组件连接在一起,这减少了关注点的分离,并且测试更加困难。

做你想做的最好的方法是使用外部服务(例如事件发射器)来管理状态。 在Flux中,这些将是“商店”。 Video组件将基于其当前状态(例如PLAYBACK_STARTED )触发动作,这会反过来更新存储。 Page组件可以触发START_PLAYBACK操作,该操作也会更新商店。 这两个组件都监听商店状态的变化,并做出相应的响应。 例如:

Page -> START_PLAYBACK -> Video (play) -> PLAYBACK_STARTED -> Page (update ui)

Flux在这里不是必需的(例如,你可以使用Redux或根本没有)。 这里重要的是清晰的单向数据流。


你可以使用refs将一个方法从一个孩子传递给它的父母。

export default class Page extends Component {
    video = (
        <Video source="some_url" ref="video" type="video/mp4" />
    );

    render = () => {
        <div onClick={ this.refs.video.play } />
    }
}

从公开组件函数

链接地址: http://www.djcxy.com/p/52147.html

上一篇: ES6 + React Component Instance Method

下一篇: Expose child component functions to parent with ref using react