Eu criei um script que é ativado na passagem do mouse em um contêiner pai e deve mover seus elementos filhos para longe do mouse. No momento, estou trabalhando, mas há algumas partes do código que parecem contradizer a aparência do código REACT. Especialmente duas partes.
Estou usando um contador na função de renderização para que cada extensão obtenha sua propriedade personalizada correta, da
state.customProperties
qual é uma matriz que atualiza as propriedades personalizadas na passagem do mouse do elemento pai.render() { let counter = 0; const returnCustomProp = function(that) { counter++; let x = 0; if (that.state.customProperties[counter - 1]) { x = that.state.customProperties[counter - 1].x; } let y = 0; if (that.state.customProperties[counter - 1]) { y = that.state.customProperties[counter - 1].y; } return "customProperty(" + x + " " + y + ")"; } return ( <div onMouseMove={this._testFunction} id="ParentContainer"> <section custom={returnCustomProp(this)}> <b>Custom content for part 1</b> <i>Could be way different from all the other elements</i> </section> <section custom={returnCustomProp(this)}> 2 </section> <section custom={returnCustomProp(this)}> <div> All content can differ internally so I'm unable to create a generic element and loop trough that </div> </section> <section custom={returnCustomProp(this)}> 4 </section> <section custom={returnCustomProp(this)}> 5 </section> <section custom={returnCustomProp(this)}> <div> <b> This is just test data, the actualy data has no divs nested inside secions </b> <h1> 6 </h1> </div> </section> <section custom={returnCustomProp(this)}> 7 </section> <section custom={returnCustomProp(this)}> 8 </section> </div> ); }
Na função mousemove, estou usando
document.getElementById
equerySelectorAll
para obter todos os elementos da seção e comparar as coordenadas do mouse e as coordenadas dos elementos da seção.var mouseX = e.pageX; var mouseY = e.pageY; var spans = document.getElementById('ParentContainer').querySelectorAll('section'); var theRangeSquared = 10 * 10; var maxOffset = 5; var newCustomProperties = []; for (var i = 0; i < spans.length; i++) { var position = spans[i].getBoundingClientRect(); var widthMod = position.width / 2; var heightMod = position.height / 2; var coordX = position.x + widthMod; var coordY = position.y + heightMod + window.scrollY; // Distance from mouse var dx = coordX - mouseX; var dy = coordY - mouseY; var distanceSquared = (dx * dx + dy * dy); var tx = 0, ty = 0; if (distanceSquared < theRangeSquared && distanceSquared !== 0) { // Calculate shift scale (inverse of distance) var shift = maxOffset * (theRangeSquared - distanceSquared) / theRangeSquared; var distance = Math.sqrt(distanceSquared); tx = shift * dx / distance; ty = shift * dy / distance; } newCustomProperties.push({ x: tx, y: ty }); }
Tenho a sensação de que estou fazendo tudo errado. Não tenho certeza de como evitar o contador, mantendo uma returnCustomProp
função genérica para retornar as propriedades do referido elemento (no código ativo, tenho cerca de 200 desses elementos, portanto, definir o número do item da matriz manualmente não é eficiente) .
A segunda parte parece hacky para direcionar um elemento por ID que está dentro do componente real. Eu sinto que deveria ser capaz de direcionar isso sem atravessar o DOM. Fazer referência aos elementos da seção pode ser uma solução, mas acredito que as referências devem ser reduzidas ao mínimo e, como afirmado, o código real consiste em centenas dessas seções.
O código não faz muito mais atm do que atualizar a custom="customProperty(0 0)"
propriedade. Você pode ver isso acontecer através do inspetor de elementos ao passar o mouse.
Posso fazer essa funcionalidade funcionar sem ter que contar os <section>
elementos dentro da função de renderização e sem precisar usar document.querySelectorAll
?
this.parentContainer
btw, deve serthis.ParentContainer
maiúsculo). Alguma idéia de como eu posso resolver o problema de usar alet counter
função de renderização dentro?sections
. Eu gostaria de manter a função genérica. Da pergunta:(in the live code I've got about 200 of these elements so setting the array item number for them manually is not efficient).
Talvez contar dentro da função render seja a maneira mais eficiente, afinal.Você não deve manipular o DOM diretamente, porque reage ao processo no dom virtual. De acordo com o documento React, você deve usar o encaminhamento de referência. Para mais detalhes , leia isto .
fonte
Você pode usar o método
findDOMNode()
de ReactDOM se você não encontrar outra solução, mas como a documentação disse:findDOMNode
é uma escotilha de escape usada para acessar o nó DOM subjacente. Na maioria dos casos, o uso dessa escotilha de escape é desencorajado porque perfura a abstração do componente.Como exemplo, quero compartilhar um caso de uso do meu aplicativo em que preciso da referência à div DOM do contêiner para implementar o arrastar e soltar para as bibliotecas que eu estava usando.
Exemplo:
fonte