簡體   English   中英

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

[英]ReactJS - Handle parent event in child event handler

我有一個我想捕獲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>
    );
}

我嘗試了一種方法,其中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
} 

我也試圖直接從myContainer中通過調用鼠標移動事件處理程序MySubComponent this.refs.SubComponent.handleMousemove但被認為是在反應-終極版不好的做法。

如果可能,應避免使用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>;
    }
}

和您的子組件:

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>;
  }
}

但是,您在子組件中的實現將如下所示。 它只需要了解其props而無需了解其父組件。

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

盡管您的mousemove應該位於子組件中,並且您的容器應使用mapDispatchtoProps,像這樣

const mapDispatchToProps = (dispatch) => {
  return {
    onmousemoveAction: (id) => {
      dispatch(toggleTodo(id))
    }
  }
}

並在您的子組件中調度(onmousemoveAction)

但是,如果您仍然想在子組件中包含邏輯,請執行

this.refs.mysubcomponent.dispatchEvent(new Event('mousedown'))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM