我有一个反应容器,我想捕获mousemove事件。这很简单。此外,我有一个由容器呈现的react子组件,其中实际上是mousemove事件处理程序的逻辑所在。所以我需要将mousemove事件从容器父项传递/委托给子项,并获取调用的子项的mousemove处理程序。怎么做得好?
我需要在容器而不是子组件中捕获鼠标事件,因为容器是DOM中较大的HTML元素,我需要捕获整个区域中的事件。
mousemove-handler-logic需要在子组件中,因为它封装了容器不应该知道的一些功能。
容器的render方法:
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
}
我还尝试通过this.refs.SubComponent.handleMousemove
直接从MyContainer调用MySubComponent中的mousemove事件处理程序,但这在react-redux中被认为是不好的做法。
答案 0 :(得分: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>;
}
}
你的孩子组成部分:
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
答案 1 :(得分:0)
虽然你的mousemove应该在子组件中,你的容器应该使用mapDispatchtoProps,就像这样
const mapDispatchToProps = (dispatch) => {
return {
onmousemoveAction: (id) => {
dispatch(toggleTodo(id))
}
}
}
并在您的子组件调度(onmousemoveAction)
中但是,如果您仍想在子组件中使用逻辑
this.refs.mysubcomponent.dispatchEvent(new Event('mousedown'))