ReactJS-在子事件处理程序中处理父事件

Mic*_*ble 2 javascript javascript-events reactjs

我有一个我想捕获mousemove事件的反应容器。这很简单。此外,我有一个由容器渲染的react子组件,该组件实际上是mousemove事件处理程序的逻辑所在。因此,我需要将mousemove事件从容器父级传递/委托给子级,并获取所调用子级的mousemove处理函数。如何正确完成?

我需要在容器而不是子组件中捕获鼠标事件,因为容器是DOM中较大的HTML元素,并且我需要在整个区域中捕获事件。

mousemove-handler-logic必须位于子组件中,因为它封装了容器不应该知道的某些功能。

容器的渲染方法:

render() {
    return (
        <div data-component="MyContainer"
             onMouseMove={(event) => this.handleMousemove(event)}>

            <MySubComponent {// ... give some props here}>
        </div>
    );
}
Run Code Online (Sandbox Code Playgroud)

我尝试了一种方法,其中MyContainer设置MySubComponent的回调函数以检索其DOM节点并向addEventListener注册处理程序,但是这种方法不能始终如一地工作,因为DOM节点有时会不确定:

export default class MyContainer extends Component {
    constructor(props) {
        super(props);
        this.state = {};

        this.getContainerRef = this.getContainerRef.bind(this);
    }

    getContainerRef() {
        return this.refs['containerWrap'];
    }

    render() {
        return (
            <div data-component="MyContainer"
                 ref="containerWrap"
                 onMouseMove={(event) => this.handleMousemove(event)}>

                <MySubComponent getContainerRef={this.getContainerRef} />
            </div>
        );
    }
}

export default class MySubComponent extends Component {
    constructor(props) {
        // ... init something

        this.handleMousemove = this.handleMousemove.bind(this);
    }

    componentDidMount() {
        // add event listener for parent application frame
        let containerDOM = this.props.getContainerRef();
        containerDOM.addEventListener('mousemove', this.handleMousemove, false);
    }

    componentWillUnmount() {
        // remove event listener from parent application frame
        let containerDOM= this.props.getContainerRef();
        containerDOM.removeEventListener('mousemove', this.handleMousemove, false);
    }

    handleMousemove(event) {
        // handle the event
    }

    // ... more methods
} 
Run Code Online (Sandbox Code Playgroud)

我还尝试通过MyContainer直接从MySubComponent调用MySubComponent中的mousemove事件处理程序,但这this.refs.SubComponent.handleMousemove在react-redux中被认为是不好的做法。

Ric*_*che 5

refs如果可能,应避免使用。

如果要onMouseMove在父容器中捕获,我认为最好是将的相关属性传递event给子组件。当值父改变componentWillReceiveProps,并shouldComponentUpdate在子组件被调用,您可以对其做出反应。

class Container extends React.Component{
  constructor(props) {
    super(props);
      this.state = {
        mouseX: 0,
        mouseY: 0
      };
    }
  handleMouse(event) {
    event.preventDefault();
    this.setState({
      mouseX: event.clientX,
      mouseY: event.clientY
    });
  }

  render() {
    return <div onMouseMove={(event) => this.handleMouse(event)} className="demo">
        <Child x={this.state.mouseX} y={this.state.mouseY} />
    </div>;
    }
}
Run Code Online (Sandbox Code Playgroud)

和您的子组件:

class Child extends React.Component {
  shouldComponentUpdate(nextProps, nextState) {
    return this.handleMouseMove(nextProps.x, nextProps.y);
  }
  handleMouseMove(x, y) {
    if (x < 150) { // return true to invoke render for some conditions
      // your code
      return true;
    }  
    return false;
  }

  render() {
    return <div>Child Component</div>;
  }
}
Run Code Online (Sandbox Code Playgroud)

但是,您在子组件中的实现将如下所示。它只需要了解其内容,props而不必了解其父组件。

反应组件生命周期:https : //facebook.github.io/react/docs/component-specs.html