I have a react container where I want to capture mousemove
events. That is pretty straight forward. Further I have a react sub-ponent rendered by the container where actually the logic for the mousemove
event handler resides. So I need to pass/delegate the mousemove
event from the container parent to the child and get the mousemove
handler of the child invoked. How is that done properly?
I need to capture the mouse event in the container rather than the sub-ponent because the container is a larger HTML element in the DOM and I need to capture events in that whole area.
The mousemove-handler-logic needs to be in the sub-ponent as it encapsulates some functionality the container should not be aware of.
The render method of the container:
render() {
return (
<div data-ponent="MyContainer"
onMouseMove={(event) => this.handleMousemove(event)}>
<MySubComponent {// ... give some props here}>
</div>
);
}
I tried an approach where MyContainer
sets callback functions for MySubComponent
to retrieve its DOM Node and register handler with addEventListener
but that did not work consistently as occasionally the DOM Node got undefined:
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-ponent="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);
}
ponentDidMount() {
// add event listener for parent application frame
let containerDOM = this.props.getContainerRef();
containerDOM.addEventListener('mousemove', this.handleMousemove, false);
}
ponentWillUnmount() {
// 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
}
I also tried to call the mousemove
event handler in MySubComponent
directly from MyContainer
via this.refs.SubComponent.handleMousemove
but that is regarded to be bad practise in react-redux.
I have a react container where I want to capture mousemove
events. That is pretty straight forward. Further I have a react sub-ponent rendered by the container where actually the logic for the mousemove
event handler resides. So I need to pass/delegate the mousemove
event from the container parent to the child and get the mousemove
handler of the child invoked. How is that done properly?
I need to capture the mouse event in the container rather than the sub-ponent because the container is a larger HTML element in the DOM and I need to capture events in that whole area.
The mousemove-handler-logic needs to be in the sub-ponent as it encapsulates some functionality the container should not be aware of.
The render method of the container:
render() {
return (
<div data-ponent="MyContainer"
onMouseMove={(event) => this.handleMousemove(event)}>
<MySubComponent {// ... give some props here}>
</div>
);
}
I tried an approach where MyContainer
sets callback functions for MySubComponent
to retrieve its DOM Node and register handler with addEventListener
but that did not work consistently as occasionally the DOM Node got undefined:
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-ponent="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);
}
ponentDidMount() {
// add event listener for parent application frame
let containerDOM = this.props.getContainerRef();
containerDOM.addEventListener('mousemove', this.handleMousemove, false);
}
ponentWillUnmount() {
// 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
}
I also tried to call the mousemove
event handler in MySubComponent
directly from MyContainer
via this.refs.SubComponent.handleMousemove
but that is regarded to be bad practise in react-redux.
-
your question has nothing to do
redux
. Can you have theonMouseMove
event directly handled byMySubComponent
? it makes more sense if the logic is pletely handled byMySubComponent
– xiaofan2406 Commented Jul 4, 2016 at 6:43 - Could you give the code of your first approach, so we can understand what went wrong? – Damien Leroux Commented Jul 4, 2016 at 7:07
- @xiaofan2406: See my edit on the question. I need to capture the event on the large HTML container element rather than on the quite small sub-ponent. – Michbeckable Commented Jul 4, 2016 at 7:32
-
@DamienLeroux: I added the code. You can see that I provide a callback function
getContainerRef
toMySubComponent
where it can retrieve the DOM ref of the container and register the event handlers itself. But when container got unmounted the provided ref always turned undefined and the event handler could not be removed. – Michbeckable Commented Jul 4, 2016 at 7:47
2 Answers
Reset to default 5Working with refs
should be avoided if possible.
If you want to capture the onMouseMove
in the parent container I think best is to just pass the relevant properties of the event
to your child ponent. When the values change in the parent ponentWillReceiveProps
and shouldComponentUpdate
in the child ponent get invoked and you can react to it.
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>;
}
}
And your Child ponent:
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>;
}
}
However your implementation in the child ponent will look like. It just has to know about its props
and nothing about its parent ponent.
react ponent lifecycle: https://facebook.github.io/react/docs/ponent-specs.html
Although your mousemove should be in the subponent and your container should use mapDispatchtoProps, like this
const mapDispatchToProps = (dispatch) => {
return {
onmousemoveAction: (id) => {
dispatch(toggleTodo(id))
}
}
}
and in your subponent dispatch(onmousemoveAction)
But if you still want to have logic in subponent do
this.refs.mysubponent.dispatchEvent(new Event('mousedown'))
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744826344a4595820.html
评论列表(0条)