2016-11-09 7 views
1

Ich rendere mehrere der gleichen Komponente, jedes mit einem eigenen Tooltip. Kann ich Code schreiben, der nur in den HTML-Code jeder Komponente passt, sodass ich nicht alle anderen Tooltips mit demselben Klassennamen betrachte? Ich verwende statusfreie Komponenten. Hier ist der Code:Wie bekomme ich ein DOM-Element innerhalb der React-Komponente?

OptionsComponent.js:

import React from 'react'; 

const OptionsComponent =() => { 
    const toggleTooltip = event => { 
    document.getElementsByClassName('listings-table-options-tooltip').classList.toggle('tooltip-hide'); 
    event.stopPropagation(); 
    }; 
    return (
    <div className="inline-block"> 
     <span onClick={toggleTooltip} className="icon icon-options listings-table-options-icon"> </span> 
     <div className="tooltip listings-table-options-tooltip"> 
      Tooltip content 
     </div> 
    </div> 
); 
}; 

Backbone.js so etwas wie dies hat, so dass Sie Ihren Umfang Dokument Abfrage innerhalb des View-Elements beginnen (analog zu einer Reaktion Komponente) .

Antwort

1

Mit React möchten Sie das DOM nicht ändern. Sie rendern Ihre Komponente nur dann neu, wenn etwas passiert. In Ihrem Fall, da Sie möchten, dass der OptionsComponent seinen eigenen Tooltip-Status verfolgt, ist er nicht einmal zustandslos. Es ist Stateful, also mach es zu einer Komponente.

Es würde wie folgt aussehen:

class OptionsComponent extends React.Component { 
    state = { 
     hide: false 
    }; 

    toggleTooltip = (ev) => this.setState({ hide: !this.state.hide }); 

    render() { 
     const ttShowHide = this.state.hide ? "tooltip-hide" : ""; 
     const ttClass = `tooltip listings-table-options-tooltip ${ttShowHide}`; 
     return (
     <div className="inline-block"> 
      <span onClick={this.toggleTooltip} className="icon icon-options listings-table-options-icon"> </span> 
      <div className={ttClass}> 
       Tooltip content 
      </div> 
     </div> 
    ); 

     // Alternatively, instead of toggling the tooltip show/hide, just don't render it! 
     return (
     <div className="inline-block"> 
      <span onClick={this.toggleTooltip} className="icon icon-options listings-table-options-icon"> </span> 
      {/* do not render the tooltip if hide is true */} 
      {!this.state.hide && 
       <div className="tooltip listings-table-options-tooltip"> 
        Tooltip content 
       </div> 
      } 
     </div> 
    ); 
    } 
} 
0

Sie sollten refs verwenden.

leicht modifiziert von React docs:

class CustomTextInput extends React.Component { 
    constructor(props) { 
    super(props); 
    this.focus = this.focus.bind(this); 
    } 

    focus() { 
    var underlyingDOMNode = this.textInput; // This is your DOM element 
    underlyingDOMNode.focus(); 
    } 

    render() { 
    // Use the `ref` callback to store a reference to the text input DOM 
    // element in this.textInput. 
    return (
     <div> 
     <input 
      type="text" 
      ref={(input) => this.textInput = input} /> 
     <input 
      type="button" 
      value="Focus the text input" 
      onClick={this.focus} 
     /> 
     </div> 
    ); 
    } 
} 
0

Eine komfortable Ansatz würde Ihre toggleTooltip Methode, um diese Art und Weise werden modifiziert:

... 
    const toggleTooltip = event => { 
     event.target.parentNode.querySelector('.tooltip').classList.toggle('tooltip-hide'); 
    }; 
... 

ich aber empfehlen würde ein Zustand mit dem Tooltip darstellen Anzeigen oder nicht .

0

Mit https://github.com/fckt/react-layer-stack können Sie gleich:

import React, { Component } from 'react'; 
import { Layer, LayerContext } from 'react-layer-stack'; 
import FixedLayer from './demo/components/FixedLayer'; 

class Demo extends Component { 
    render() { 
    return (
     <div> 
     <Layer id="lightbox2">{ (_, content) => 
      <FixedLayer style={ { marginRight: '15px', marginBottom: '15px' } }> 
      { content } 
      </FixedLayer> 
     }</Layer> 

     <LayerContext id="lightbox2">{({ showMe, hideMe }) => (
      <button onMouseLeave={ hideMe } onMouseMove={ ({ pageX, pageY }) => { 
       showMe(
       <div style={{ 
         left: pageX, top: pageY + 20, position: "absolute", 
         padding: '10px', 
         background: 'rgba(0,0,0,0.7)', color: '#fff', borderRadius: '5px', 
         boxShadow: '0px 0px 50px 0px rgba(0,0,0,0.60)'}}> 
        “There has to be message triage. If you say three things, you don’t say anything.” 
       </div>) 
      }}>Yet another button. Move your pointer to it.</button>)} 
      </LayerContext> 
     </div> 
    ) 
    } 
} 
Verwandte Themen