samedi 28 février 2015

React child component only fires 'onTouchMove' event once


** I'm pretty confident I can figure out a work around to the specific example given, I'm asking for help on SO to gain better knowledge of React specific idiosyncrasies of DOM creation and events. **


I setup a component that manages multiple components. These children have onMouseMove and onTouchMove events that call handler functions on the parent.


For context, the children components are timeline charts. When one child sees mouseover, it calls the parent handler function to figure out what time was moused over, then renders the same time on all of the children.


This works great in the browser with onMouseMove, the issue I'm having is when I try to add the same functionality to mobile touch browsers with onTouchMove. The initial onTouchMove event is called, but "this.setState({})" function called on the parent updates the children once, and no more touchmove events are called. Ideally a user could slide their finger along one charts timeline, and all the charts would continuously select the same hour of their timeline.


The timeline chart inside the children components are wrapped in a React.DOM.div, that is where the onTouchMove and onMouseMove calls are being generated, I can post that code too if needed.


If the only thing I change on the parent is it's state.index (there are no dom changes), and there are no dom changes in the children components above the wrapper element (only dom changes are inside the wrapper element), then shouldn't the wrappers onTouchMove events continue to fire? (side note, if I comment out "this.setState({})" from the parent handler and replace with a console.log call it will call continuously, so I know the code is working).


SO the question: why is the child component loosing it's current onTouchMove event? I'm new to react so could be missing something.


Thanks!



// simplified example:

var parentComponent = React.createFactory(
React.createClass({
getInitialState: function(){
return { index: this.props.index || -1 };
},
handle_container_mouse_move: function(evt){
var chart = evt.currentTarget;
var grid = chart.querySelector('.ct-grids');
var bbox = grid.getBBox();
var division = bbox.width / chart.querySelectorAll('.ct-series > line').length;
var x = evt.clientX - bbox.x - chart.offsetLeft - (division/2);
this.setState({ index: Math.round(x / division) });
},
handle_container_touch_move: function(evt){
var chart = evt.currentTarget;
var grid = chart.querySelector('.ct-grids');
var bbox = grid.getBBox();
var division = bbox.width / chart.querySelectorAll('.ct-series > line').length;
var x = evt.touches[0].clientX - bbox.x - chart.offsetLeft - (division/2);
this.setState({ index: Math.round(x / division) });
},
render: function(){

var children = [];

... other code ...

children.push(childComponent({
key: 'some_key',
index: this.state.index,
handle_child_mouse_move: this.handle_container_mouse_move,
handle_child_touch_move: this.handle_container_touch_move
}))

... other code ...

return React.DOM.div({}, children );

}}
}));


Thanks!


* edit *


It seams whenever a React component touches the dom it breaks touchmove:



// this will log lots of 'now's on console.log as the touch moves

$(document).on('touchmove', function(evt) {
console.log('now');
document.body.appendChild(document.createElement('div'));
});


// this will log only one 'now' on console.log

$(document).on('touchmove', function(evt) {
console.log('now');
React.render(CountyList({ time: 6 }), $state_list_container[0] );
});




Aucun commentaire:

Enregistrer un commentaire