Element in React ein- oder ausblenden

532

Ich spiele zum ersten Mal mit React.js herum und kann keine Möglichkeit finden, etwas auf einer Seite über ein Klickereignis ein- oder auszublenden. Ich lade keine andere Bibliothek auf die Seite, daher suche ich nach einer nativen Möglichkeit, die React-Bibliothek zu verwenden. Das habe ich bisher. Ich möchte die Ergebnisse div anzeigen, wenn das Klickereignis ausgelöst wird.

var Search= React.createClass({
    handleClick: function (event) {
        console.log(this.prop);
    },
    render: function () {
        return (
            <div className="date-range">
                <input type="submit" value="Search" onClick={this.handleClick} />
            </div>
        );
    }
});

var Results = React.createClass({
    render: function () {
        return (
            <div id="results" className="search-results">
                Some Results
            </div>
        );
    }
});

React.renderComponent(<Search /> , document.body);
user1725382
quelle
11
Der akzeptierte Kommentar verwendet neuartige Technologien, um das zu tun, was vorhandene Technologien auf nativer Ebene einfacher, schneller und gemeinsam mit anderen Sprachen und Bibliotheken tun können. Dies mit Standard-CSS zu handhaben, ist mit ziemlicher Sicherheit die bessere Antwort.
John Haugeland
13
@ JohnHaugeland, die beste Antwort bei Verwendung des React-Frameworks ist die akzeptierte Antwort, die alle React-Stile verwendet und über Bereinigungsfunktionen verfügt, die Sie in einigen Fällen ausführen müssen. Es ist keine gute Praxis, Komponenten nur im Dunkeln zu verstecken. Wenn Sie Sachen mischen, werden Sie besser ganz einheimisch, was immer schneller ist als alles andere.
Claudiu Hojda
4
Nein, das ist es wirklich nicht. Die Verwendung von React zur Neuerfindung von CSS ist eine schlechte Idee.
John Haugeland
8
Außerdem scheinen Sie den Punkt, den ich gesagt habe, völlig übersehen zu haben, nämlich CSS zu verwenden, um das Element zu verbergen und anzuzeigen, anstatt React zu verwenden, um es physisch zu entfernen. Mit React können Sie CSS verwenden, um das Element genauso einfach auszublenden und anzuzeigen: <div style = {{display: this.props.example}} />.
John Haugeland
5
@ClaudiuHojda, bei dem Komponenten im Dunkeln versteckt sind, ist in einigen Fällen eine sehr gute Praxis. Ich denke an eine reaktionsschnelle Navigation, bei der die Links im HTML-Code verbleiben müssen, auch wenn sie mit CSS verborgen sind
Toni Leigh

Antworten:

545

Reagiere um 2020

onClickRufen Sie im Rückruf die Setter-Funktion des Status- Hooks auf, um den Status zu aktualisieren und erneut zu rendern:

const Search = () => {
  const [showResults, setShowResults] = React.useState(false)
  const onClick = () => setShowResults(true)
  return (
    <div>
      <input type="submit" value="Search" onClick={onClick} />
      { showResults ? <Results /> : null }
    </div>
  )
}

const Results = () => (
  <div id="results" className="search-results">
    Some Results
  </div>
)

ReactDOM.render(<Search />, document.querySelector("#container"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>

<div id="container">
  <!-- This element's contents will be replaced with your component. -->
</div>

JSFiddle

Reagiere um 2014

Der Schlüssel besteht darin, den Status der Komponente im Klick-Handler mit zu aktualisieren setState. Wenn die Statusänderungen angewendet werden, wird die renderMethode mit dem neuen Status erneut aufgerufen:

var Search = React.createClass({
    getInitialState: function() {
        return { showResults: false };
    },
    onClick: function() {
        this.setState({ showResults: true });
    },
    render: function() {
        return (
            <div>
                <input type="submit" value="Search" onClick={this.onClick} />
                { this.state.showResults ? <Results /> : null }
            </div>
        );
    }
});

var Results = React.createClass({
    render: function() {
        return (
            <div id="results" className="search-results">
                Some Results
            </div>
        );
    }
});

ReactDOM.render( <Search /> , document.getElementById('container'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.2/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/15.6.2/react-dom.min.js"></script>

<div id="container">
  <!-- This element's contents will be replaced with your component. -->
</div>

JSFiddle

Douglas
quelle
3
Ja, guter Punkt über Staat gegen Requisiten. Ein besserer Weg, dies zu tun, wäre wie im Tutorial hier, wo die Suchleiste und die Ergebnistabelle Geschwister sind, anstatt Ergebnisse in die Suche einzufügen
Douglas
53
Wie in der anderen Antwort erwähnt, ist das Einfügen / Löschen viel langsamer als die einfache Klassenmaskierung.
John Haugeland
4
Ich denke, Johns Kommentare müssen überprüft werden. Ich ging mit der beabsichtigten Antwort und das war ordentlich und fühlte sich eher wie reagieren. Ich konnte jedoch keine Anfangszustände und nichts Nützliches für eine nicht gemountete Komponente festlegen. Ich möchte stattdessen CSS verwenden, um Dinge zu verbergen. Listener auf nicht gemounteten Komponenten werden lautlos versagen. Dies hat mir heute einen großen Zeitverlust verursacht.
landete
Bedeutet das, dass durch Reagieren die Komponente erneut gerendert wird, wenn sich der Stil ändert (wird ein- / ausgeblendet)!
Alex
@Douglas Wenn ich es nicht verpasst habe, kann auf diese Weise nicht zum Original zurückgeschaltet werden. Ich denke, das OP hat es vielleicht nicht gewollt, aber wie kann ich das einbeziehen?
Der Wurm
221
<style type="text/css">
    .hidden { display:none; }
</style>
render: function() {
    return (
      <div className={this.props.shouldHide ? 'hidden' : ''}>
        This will be hidden if you set <tt>props.shouldHide</tt> 
        to something truthy.
      </div>
    );
}

// or in more modern JS and stateless react
const Example = props => <div className={props.shouldHide}/>Hello</div>
John Haugeland
quelle
12
Es ist besser, bedingt null zurückzugeben, wie in Douglas 'Antwort. Dadurch kann React es vollständig aus dem DOM entfernen. In Ihrem Fall werden das div und sein Inhalt immer noch im DOM angezeigt. Dies kann Auswirkungen auf die Leistung haben.
pmont
125
Die Auswirkungen auf die Leistung sind beim Hinzufügen und Entfernen eines dom-Elements viel schlimmer als beim Ausblenden und Anzeigen. Ich bin mir des Unterschieds zwischen seinem und meinem Ansatz bewusst, und ich glaube, dass Sie genau das falsch machen. Bitte nehmen Sie sich die Zeit, um "Auswirkungen auf die Leistung" zu definieren und diese dann zu messen.
John Haugeland
6
"Reflows sind durch Hinzufügen / Entfernen garantiert" - Nicht mit absolut positionierten Elementen, so erhält Famous seine unglaubliche Leistung. Sie machen jedoch einen gültigen Punkt in den Metriken.
pmont
9
Für das, was es wert ist, wird dies in den Reaktionsdokumenten hier erwähnt: facebook.github.io/react/docs/…
Brad Parks
85
Also habe ich gerade getestet, wie man null zurückgibt, anstatt eine versteckte Klasse mit 161 ziemlich großen Dom-Knoten zu setzen. Die Verwendung einer Klasse ist erheblich schneller als das Entfernen des Knotens.
Jonathan Rowny
120

Hier ist eine alternative Syntax für den ternären Operator:

{ this.state.showMyComponent ? <MyComponent /> : null }

ist äquivalent zu:

{ this.state.showMyComponent && <MyComponent /> }

Lean warum


Auch alternative Syntax mit display: 'none';

<MyComponent style={this.state.showMyComponent ? {} : { display: 'none' }} />

Wenn Sie jedoch zu viel verwenden display: 'none', führt dies zu einer DOM-Verschmutzung und verlangsamt letztendlich Ihre Anwendung.

Lyubomir
quelle
Warnung! Verwenden Sie den Ansatz 'Double Ampersand (&&)' nur für Bool-Werte. {this.state.myComponents.length && <MyComponent />} rendert 0, wenn myComponents (zum Beispiel) ein leeres Array enthält
Mega Proger
57

Hier ist mein Ansatz.

import React, { useState } from 'react';

function ToggleBox({ title, children }) {
  const [isOpened, setIsOpened] = useState(false);

  function toggle() {
    setIsOpened(wasOpened => !wasOpened);
  }

  return (
    <div className="box">
      <div className="boxTitle" onClick={toggle}>
        {title}
      </div>
      {isOpened && (
        <div className="boxContent">
          {children}
        </div>
      )}
    </div>
  );
}

Um dies zu erreichen, verwende ich im obigen Code folgenden Code:

{opened && <SomeElement />}

Das wird SomeElementnur gerendert , wenn openedes wahr ist. Es funktioniert aufgrund der Art und Weise, wie JavaScript logische Bedingungen auflöst:

true && true && 2; // will output 2
true && false && 2; // will output false
true && 'some string'; // will output 'some string'
opened && <SomeElement />; // will output SomeElement if `opened` is true, will output false otherwise (and false will be ignored by react during rendering)
// be careful with 'falsy' values eg
const someValue = 0;
someValue && <SomeElement /> // will output 0, which will be rednered by react
// it'll be better to:
!!someValue && <SomeElement /> // will render nothing as we cast the value to boolean

Gründe für die Verwendung dieses Ansatzes anstelle von CSS 'Anzeige: keine';

  • Während es möglicherweise "billiger" ist, ein Element mit CSS auszublenden, ist in diesem Fall das "versteckte" Element in der Reaktionswelt noch "lebendig" (was es möglicherweise viel teurer macht).
    • Dies bedeutet, dass <TabView>alle 5 Registerkarten neu gerendert werden , wenn sich die Requisiten des übergeordneten Elements (z. B. ) ändern - selbst wenn Sie nur eine Registerkarte sehen
    • Auf dem versteckten Element werden möglicherweise noch einige Lebenszyklusmethoden ausgeführt - z. Möglicherweise werden nach jedem Update einige Daten vom Server abgerufen, obwohl sie nicht sichtbar sind
    • Das versteckte Element kann die App zum Absturz bringen, wenn falsche Daten empfangen werden. Dies kann passieren, wenn Sie beim Aktualisieren des Status unsichtbare Knoten "vergessen" können
    • Sie könnten versehentlich einen falschen Anzeigestil einstellen, wenn Sie ein Element sichtbar machen - z. Einige Divs sind standardmäßig 'display: flex', aber Sie setzen versehentlich 'display: block', display: invisible ? 'block' : 'none'wodurch das Layout möglicherweise beschädigt wird
    • Die Verwendung someBoolean && <SomeNode />ist sehr einfach zu verstehen und zu begründen, insbesondere wenn Ihre Logik in Bezug auf die Anzeige von etwas oder nicht komplex wird
    • In vielen Fällen möchten Sie den Elementstatus zurücksetzen, wenn er erneut angezeigt wird. z.B. Möglicherweise haben Sie einen Schieberegler, den Sie bei jeder Anzeige auf die Ausgangsposition setzen möchten. (Wenn dies das gewünschte Verhalten ist, um den vorherigen Elementstatus beizubehalten, auch wenn es ausgeblendet ist, was IMO selten ist - ich würde in der Tat die Verwendung von CSS in Betracht ziehen, wenn es kompliziert wäre, sich diesen Status auf eine andere Weise zu merken.)
pie6k
quelle
2
Dies ist ein großartiges Beispiel! Eine kleine Sache, boxContent sollte className = "boxContent" sein
Bhetzie
5
Hier gibt es einen Fehler : this.setState({isOpened: !isOpened});. Hängen Sie nicht vom Status selbst ab, wenn Sie den Status ändern. Hier ist ein gutes Beispiel: reactjs.org/docs/… So sollte es sein : this.setState( s => ({isOpened: !s.isOpened}) ). Beachten Sie die Pfeilfunktion in setState.
Arcol
Haben Sie eine Quelle / einen Benchmark / ein Beispiel, die dies bestätigt? "Wenn Sie die Anzeige einstellen: none - Element wird immer noch durch React gerendert und zu DOM hinzugefügt - kann dies negative Auswirkungen auf die Leistung haben." ?
Neiya
@neiya ich nicht. CSS ist mit kleinen Elementen möglicherweise leistungsfähiger, aber häufig möchten Sie optional große Teile des Inhalts rendern, z. Tab. Auch wenn ein Element in CSS verborgen ist, lebt es in der Reaktionswelt noch. Dies bedeutet, dass der Status möglicherweise aktualisiert, Daten usw. abgerufen werden. Dies kann teuer sein und zu unerwartetem Verhalten führen. Und es ist IMO eigentlich sehr einfach zu implementieren.
pie6k
17

Mit der neuesten Version von React 0.11 können Sie auch einfach null zurückgeben, damit kein Inhalt gerendert wird.

Auf Null rendern

squiddle
quelle
11

Ich habe eine kleine Komponente erstellt, die dies für Sie erledigt: React-Toggle-Display

Es setzt das Stilattribut display: none !importantbasierend auf den Requisiten hideoder show.

Anwendungsbeispiel:

var ToggleDisplay = require('react-toggle-display');

var Search = React.createClass({
    getInitialState: function() {
        return { showResults: false };
    },
    onClick: function() {
        this.setState({ showResults: true });
    },
    render: function() {
        return (
            <div>
                <input type="submit" value="Search" onClick={this.onClick} />
                <ToggleDisplay show={this.state.showResults}>
                    <Results />
                </ToggleDisplay>
            </div>
        );
    }
});

var Results = React.createClass({
    render: function() {
        return (
            <div id="results" className="search-results">
                Some Results
            </div>
        );
    }
});

React.renderComponent(<Search />, document.body);
ccnokes
quelle
10

Es gibt bereits einige großartige Antworten, aber ich denke nicht, dass sie sehr gut erklärt wurden, und einige der angegebenen Methoden enthalten einige Fallstricke, die die Leute stören könnten. Ich werde also die drei Hauptwege (plus eine Option außerhalb des Themas) durchgehen, um dies zu tun und die Vor- und Nachteile zu erklären. Ich schreibe dies hauptsächlich, weil Option 1 sehr empfohlen wurde und es viele potenzielle Probleme mit dieser Option gibt, wenn sie nicht richtig verwendet wird.

Option 1: Bedingtes Rendern im übergeordneten Element.

Diese Methode gefällt mir nur, wenn Sie die Komponente nur einmal rendern und dort belassen. Das Problem ist, dass jedes Mal, wenn Sie die Sichtbarkeit umschalten, die Komponente von Grund auf neu erstellt wird. Hier ist das Beispiel. LogoutButton oder LoginButton werden im übergeordneten LoginControl bedingt gerendert. Wenn Sie dies ausführen, werden Sie feststellen, dass der Konstruktor bei jedem Klick auf die Schaltfläche aufgerufen wird. https://codepen.io/Kelnor/pen/LzPdpN?editors=1111

class LoginControl extends React.Component {
  constructor(props) {
    super(props);
    this.handleLoginClick = this.handleLoginClick.bind(this);
    this.handleLogoutClick = this.handleLogoutClick.bind(this);
    this.state = {isLoggedIn: false};
  }

  handleLoginClick() {
    this.setState({isLoggedIn: true});
  }

  handleLogoutClick() {
    this.setState({isLoggedIn: false});
  }

  render() {
    const isLoggedIn = this.state.isLoggedIn;

    let button = null;
    if (isLoggedIn) {
      button = <LogoutButton onClick={this.handleLogoutClick} />;
    } else {
      button = <LoginButton onClick={this.handleLoginClick} />;
    }

    return (
      <div>
        <Greeting isLoggedIn={isLoggedIn} />
        {button}
      </div>
    );
  }
}

class LogoutButton extends React.Component{
  constructor(props, context){
    super(props, context)
    console.log('created logout button');
  }
  render(){
    return (
      <button onClick={this.props.onClick}>
        Logout
      </button>
    );
  }
}

class LoginButton extends React.Component{
  constructor(props, context){
    super(props, context)
    console.log('created login button');
  }
  render(){
    return (
      <button onClick={this.props.onClick}>
        Login
      </button>
    );
  }
}

function UserGreeting(props) {
  return <h1>Welcome back!</h1>;
}

function GuestGreeting(props) {
  return <h1>Please sign up.</h1>;
}

function Greeting(props) {
  const isLoggedIn = props.isLoggedIn;
  if (isLoggedIn) {
    return <UserGreeting />;
  }
  return <GuestGreeting />;
}

ReactDOM.render(
  <LoginControl />,
  document.getElementById('root')
);

Jetzt ist React ziemlich schnell darin, Komponenten von Grund auf neu zu erstellen. Es muss jedoch immer noch Ihren Code aufrufen, wenn Sie ihn erstellen. Wenn Ihr Konstruktor-, componentDidMount-, Rendering- usw. Code also teuer ist, wird die Anzeige der Komponente erheblich verlangsamt. Dies bedeutet auch, dass Sie dies nicht für statusbehaftete Komponenten verwenden können, bei denen der Status beim Ausblenden beibehalten (und beim Anzeigen wiederhergestellt) werden soll. Der einzige Vorteil besteht darin, dass die ausgeblendete Komponente erst erstellt wird, wenn sie ausgewählt ist. Versteckte Komponenten verzögern also nicht das anfängliche Laden der Seite. Es kann auch Fälle geben, in denen Sie möchten, dass eine Stateful-Komponente beim Umschalten zurückgesetzt wird. In diesem Fall ist dies die beste Option.

Option 2: Bedingtes Rendern im Kind

Dadurch werden beide Komponenten einmal erstellt. Schließen Sie dann den Rest des Rendercodes kurz, wenn die Komponente ausgeblendet ist. Sie können auch andere Logik in anderen Methoden mit der sichtbaren Stütze kurzschließen. Beachten Sie das console.log auf der Codepen-Seite. https://codepen.io/Kelnor/pen/YrKaWZ?editors=0011

class LoginControl extends React.Component {
  constructor(props) {
    super(props);
    this.handleLoginClick = this.handleLoginClick.bind(this);
    this.handleLogoutClick = this.handleLogoutClick.bind(this);
    this.state = {isLoggedIn: false};
  }

  handleLoginClick() {
    this.setState({isLoggedIn: true});
  }

  handleLogoutClick() {
    this.setState({isLoggedIn: false});
  }

  render() {
    const isLoggedIn = this.state.isLoggedIn;
    return (
      <div>
        <Greeting isLoggedIn={isLoggedIn} />
        <LoginButton isLoggedIn={isLoggedIn} onClick={this.handleLoginClick}/>
        <LogoutButton isLoggedIn={isLoggedIn} onClick={this.handleLogoutClick}/>
      </div>
    );
  }
}

class LogoutButton extends React.Component{
  constructor(props, context){
    super(props, context)
    console.log('created logout button');
  }
  render(){
    if(!this.props.isLoggedIn){
      return null;
    }
    return (
      <button onClick={this.props.onClick}>
        Logout
      </button>
    );
  }
}

class LoginButton extends React.Component{
  constructor(props, context){
    super(props, context)
    console.log('created login button');
  }
  render(){
    if(this.props.isLoggedIn){
      return null;
    }
    return (
      <button onClick={this.props.onClick}>
        Login
      </button>
    );
  }
}

function UserGreeting(props) {
  return <h1>Welcome back!</h1>;
}

function GuestGreeting(props) {
  return <h1>Please sign up.</h1>;
}

function Greeting(props) {
  const isLoggedIn = props.isLoggedIn;
  if (isLoggedIn) {
    return <UserGreeting />;
  }
  return <GuestGreeting />;
}

ReactDOM.render(
  <LoginControl />,
  document.getElementById('root')
);

Wenn die Initialisierungslogik schnell ist und die untergeordneten Elemente zustandslos sind, werden Sie keinen Unterschied in der Leistung oder Funktionalität feststellen. Warum sollte React jedoch bei jedem Umschalten eine brandneue Komponente erstellen? Wenn die Initialisierung jedoch teuer ist, wird sie bei Option 1 jedes Mal ausgeführt, wenn Sie eine Komponente umschalten, die die Seite beim Wechseln verlangsamt. Option 2 führt alle Inits der Komponente beim Laden der ersten Seite aus. Die erste Ladung verlangsamen. Sollte nochmal notieren. Wenn Sie die Komponente nur einmal basierend auf einer Bedingung anzeigen und nicht umschalten oder möchten, dass sie beim Umschalten zurückgesetzt wird, ist Option 1 in Ordnung und wahrscheinlich die beste Option.

Wenn das langsame Laden von Seiten jedoch ein Problem darstellt, bedeutet dies, dass Sie in einer Lebenszyklusmethode teuren Code haben, und das ist im Allgemeinen keine gute Idee. Sie können und sollten wahrscheinlich das langsame Laden von Seiten lösen, indem Sie den teuren Code aus den Lebenszyklusmethoden entfernen. Verschieben Sie es in eine asynchrone Funktion, die von ComponentDidMount gestartet wurde, und lassen Sie den Rückruf es mit setState () in eine Statusvariable setzen. Wenn die Statusvariable null ist und die Komponente sichtbar ist, muss die Renderfunktion einen Platzhalter zurückgeben. Andernfalls rendern Sie die Daten. Auf diese Weise wird die Seite schnell geladen und die Registerkarten werden beim Laden gefüllt. Sie können die Logik auch in das übergeordnete Element verschieben und die Ergebnisse als Requisiten an die untergeordneten Elemente senden. Auf diese Weise können Sie priorisieren, welche Registerkarten zuerst geladen werden. Oder speichern Sie die Ergebnisse im Cache und führen Sie die Logik nur aus, wenn eine Komponente zum ersten Mal angezeigt wird.

Option 3: Klassenverstecken

Das Verstecken von Klassen ist wahrscheinlich am einfachsten zu implementieren. Wie bereits erwähnt, erstellen Sie einfach eine CSS-Klasse mit display: none und weisen die Klasse basierend auf prop zu. Der Nachteil ist, dass der gesamte Code jeder versteckten Komponente aufgerufen wird und alle versteckten Komponenten an das DOM angehängt werden. (Option 1 erstellt die ausgeblendeten Komponenten überhaupt nicht. Und Option 2 schließt unnötigen Code kurz, wenn die Komponente ausgeblendet ist, und entfernt die Komponente vollständig aus dem DOM.) Es scheint, dass dies beim Umschalten der Sichtbarkeit nach einigen von Kommentatoren durchgeführten Tests schneller ist andere Antworten, aber ich kann nicht mit ihnen sprechen.

Option 4: Eine Komponente, aber Requisiten ändern. Oder vielleicht überhaupt keine Komponente und HTML zwischenspeichern.

Dieser funktioniert nicht für jede Anwendung und ist kein Thema, da es nicht darum geht, Komponenten auszublenden, aber für einige Anwendungsfälle ist er möglicherweise eine bessere Lösung als das Ausblenden. Angenommen, Sie haben Registerkarten. Möglicherweise können Sie eine Reaktionskomponente schreiben und mit den Requisiten ändern, was auf der Registerkarte angezeigt wird. Sie können JSX auch in Statusvariablen speichern und mithilfe einer Requisite entscheiden, welche JSX in der Renderfunktion zurückgegeben werden soll. Wenn die JSX generiert werden muss, tun Sie dies und zwischenspeichern Sie sie im übergeordneten Element und senden Sie die richtige als Requisite. Oder generieren Sie im Kind und zwischenspeichern Sie es im Zustand des Kindes und verwenden Sie Requisiten, um das aktive auszuwählen.

Kelnor
quelle
9

Dies ist eine gute Möglichkeit, das virtuelle DOM zu nutzen :

class Toggle extends React.Component {
  state = {
    show: true,
  }

  toggle = () => this.setState((currentState) => ({show: !currentState.show}));

  render() {
    return (
      <div>
        <button onClick={this.toggle}>
          toggle: {this.state.show ? 'show' : 'hide'}
        </button>    
        {this.state.show && <div>Hi there</div>}
      </div>
     );
  }
}

Beispiel hier

React Hooks verwenden:

const Toggle = () => {
  const [show, toggleShow] = React.useState(true);

  return (
    <div>
      <button
        onClick={() => toggleShow(!show)}
      >
        toggle: {show ? 'show' : 'hide'}
      </button>    
      {show && <div>Hi there</div>}
    </div>
  )
}

Beispiel hier

Daniloprate
quelle
Ich mag diese schlanke Antwort. Schade, dass die Geige nicht rennen würde.
Juan Lanus
Wie in einer früheren Antwort erwähnt, sollten Sie nicht vom Status in abhängig seinthis.setState() .
Dan Dascalescu
8

Sie setzen einen booleschen Wert im Status (z. B. 'show)' und führen dann Folgendes aus:

var style = {};
if (!this.state.show) {
  style.display = 'none'
}

return <div style={style}>...</div>
Räuber
quelle
Ich habe es versucht, aber das Klickereignis hat das CSS nicht auf Anzeigeblock umgestellt. Ich weiß nicht genau, wie ich das erreichen soll. Irgendwelche zusätzlichen Tipps?
user1725382
1
Dies beinhaltet aktive Änderungen an der Stilregel-Tabelle. Es ist viel besser, eine einzige vorhandene Regel zu haben, die Sie ein- und ausschalten können. Dies ist nicht Teil der dynamischen Eigenschaften des Dom-Knotens.
John Haugeland
1
Es ist wirklich egal, ob Sie hier eine Klasse oder einen Stil verwenden ... Sie scheinen darüber sehr aufgeregt zu sein.
Brigand
2
Die Verwendung einer Klasse ist um einige Größenordnungen schneller. Es ist gut zu wissen.
Jason Rice
1
Könnte nur bedingte Klassennamen verwenden mit: github.com/JedWatson/classnames
Backdesk
7

Best Practice finden Sie unten in der Dokumentation:

{this.state.showFooter && <Footer />}

Rendern Sie das Element nur, wenn der Status gültig ist.

Dynamisch
quelle
Diese Antwort wurde bereits gegeben ein Jahr zuvor, so ist es OK , um es jetzt zu löschen.
Dan Dascalescu
5
class Toggle extends React.Component {
  state = {
    show: true,
  }

  render() {
    const {show} = this.state;
    return (
      <div>
        <button onClick={()=> this.setState({show: !show })}>
          toggle: {show ? 'show' : 'hide'}
        </button>    
        {show && <div>Hi there</div>}
      </div>
     );
  }
}
sgr
quelle
4
   class FormPage extends React.Component{
      constructor(props){
           super(props);
           this.state = {
             hidediv: false
           }
      }

     handleClick = (){
       this.setState({
          hidediv: true
        });
      }

      render(){
        return(
        <div>
          <div className="date-range" hidden = {this.state.hidediv}>
               <input type="submit" value="Search" onClick={this.handleClick} />
          </div>
          <div id="results" className="search-results" hidden = {!this.state.hidediv}>
                        Some Results
           </div>
        </div>
        );
      }
  }
Akanksha Gore
quelle
4

Ich beginne mit dieser Aussage des React-Teams:

In React können Sie verschiedene Komponenten erstellen, die das von Ihnen benötigte Verhalten kapseln. Anschließend können Sie je nach Status Ihrer Anwendung nur einige davon rendern.

Das bedingte Rendern in React funktioniert genauso wie die Bedingungen in JavaScript. Verwenden Sie JavaScript-Operatoren wie if oder den bedingten Operator, um Elemente zu erstellen, die den aktuellen Status darstellen, und lassen Sie React die Benutzeroberfläche entsprechend aktualisieren.

Grundsätzlich müssen Sie die Komponente anzeigen, wenn auf die Schaltfläche geklickt wird. Sie können dies auf zwei Arten tun: mit reinem React oder mit CSS. Mit reinem React-Weg können Sie in Ihrem Fall so etwas wie den folgenden Code ausführen, sodass im ersten Durchgang Ergebnisse erzielt werden werden nicht so angezeigt, wie sie hideResultssind true, aber durch Klicken auf die Schaltfläche ändert sich der Status und hideResultswird falseund die Komponente wird erneut mit den neuen Wertebedingungen gerendert. Dies ist eine sehr häufige Verwendung der Änderung der Komponentenansicht in React ...

var Search = React.createClass({
  getInitialState: function() {
    return { hideResults: true };
  },

  handleClick: function() {
    this.setState({ hideResults: false });
  },

  render: function() {
    return (
      <div>
        <input type="submit" value="Search" onClick={this.handleClick} />
        { !this.state.hideResults && <Results /> }
      </div> );
  }

});

var Results = React.createClass({
  render: function() {
    return (
    <div id="results" className="search-results">
      Some Results
    </div>);
   }
});

ReactDOM.render(<Search />, document.body);

Wenn Sie weitere Studien zum bedingten Rendern in React durchführen möchten, klicken Sie hier .

Alireza
quelle
1
Dies sollte der eleganteste Weg sein!
fünfter
4

Einfaches Ein- / Ausblenden-Beispiel mit React Hooks: (srry about no fiddle)

const Example = () => {

  const [show, setShow] = useState(false);

  return (
    <div>
      <p>Show state: {show}</p>
      {show ? (
        <p>You can see me!</p>
      ) : null}
      <button onClick={() => setShow(!show)}>
    </div>
  );

};

export default Example;
StefanBob
quelle
2
es kann einfacher sein, nur {zu zeigen? 1: 2}
Piotr Żak
3

Wenn Sie sehen möchten, wie Sie die Anzeige einer Komponente umschalten können, überprüfen Sie diese Geige.

http://jsfiddle.net/mnoster/kb3gN/16387/

var Search = React.createClass({
    getInitialState: function() {
        return { 
            shouldHide:false
        };
    },
    onClick: function() {
        console.log("onclick");
        if(!this.state.shouldHide){
            this.setState({
                shouldHide: true 
            })
        }else{
                    this.setState({
                shouldHide: false 
            })
        }
    },
render: function() {
    return (
      <div>
        <button onClick={this.onClick}>click me</button>
        <p className={this.state.shouldHide ? 'hidden' : ''} >yoyoyoyoyo</p>
      </div>
    );
}
});

ReactDOM.render( <Search /> , document.getElementById('container'));
Nicholas Porter
quelle
3

Eine einfache Methode zum Ein- und Ausblenden von Elementen in React using Hooks

const [showText, setShowText] = useState(false);

Fügen wir nun unserer Rendermethode eine Logik hinzu:

{showText && <div>This text will show!</div>}

Und

onClick={() => setShowText(!showText)}

Gut gemacht.

Superup
quelle
2

In einigen Fällen kann eine Komponente höherer Ordnung nützlich sein:

Komponente höherer Ordnung erstellen:

export var HidableComponent = (ComposedComponent) => class extends React.Component {
    render() {
        if ((this.props.shouldHide!=null && this.props.shouldHide()) || this.props.hidden)
            return null;
        return <ComposedComponent {...this.props}  />;
    }
};

Erweitern Sie Ihre eigene Komponente:

export const MyComp= HidableComponent(MyCompBasic);

Dann können Sie es so verwenden:

<MyComp hidden={true} ... />
<MyComp shouldHide={this.props.useSomeFunctionHere} ... />

Dies reduziert ein wenig das Boilerplate und erzwingt das Festhalten an Namenskonventionen. Beachten Sie jedoch, dass MyComp weiterhin instanziiert wird - der Weg zum Weglassen wurde bereits erwähnt:

{ !hidden && <MyComp ... /> }

Vinga
quelle
1

Verwenden Sie das Modul rc-if-else

npm install --save rc-if-else
import React from 'react';
import { If } from 'rc-if-else';

class App extends React.Component {
    render() {
        return (
            <If condition={this.props.showResult}>
                Some Results
            </If>
        );
    }
}
Qinyuanbin
quelle
1

Verwenden Sie ref und manipulieren Sie CSS

Eine Möglichkeit könnte darin bestehen, die React- refKlasse zu verwenden und die CSS-Klasse mithilfe der Browser-API zu bearbeiten. Der Vorteil besteht darin, ein erneutes Rendern in React zu vermeiden, wenn der einzige Zweck darin besteht, ein DOM-Element auf Knopfdruck auszublenden / anzuzeigen.

// Parent.jsx
import React, { Component } from 'react'

export default class Parent extends Component {
    constructor () {    
        this.childContainer = React.createRef()
    }

    toggleChild = () => {
        this.childContainer.current.classList.toggle('hidden')
    }

    render () {
        return (
            ...

            <button onClick={this.toggleChild}>Toggle Child</button>
            <div ref={this.childContainer}>
                <SomeChildComponent/>
            </div>

            ...
        );
    }
}


// styles.css
.hidden {
    display: none;
}

PS Korrigieren Sie mich, wenn ich falsch liege. :) :)

UtkarshPramodGupta
quelle
Erstellt Codesandbox.io Beispiel, hier: utgzx.csb.app , Code ist bei Codesandbox.io/embed/react-show-hide-with-css-utgzx
PatS
0

Wenn Sie Bootstrap 4 verwenden, können Sie das Element auf diese Weise ausblenden

className={this.state.hideElement ? "invisible" : "visible"}
ThomasP1988
quelle
0

Dies kann auch so erreicht werden (sehr einfacher Weg)

 class app extends Component {
   state = {
     show: false
   };
 toggle= () => {
   var res = this.state.show;
   this.setState({ show: !res });
 };
render() {
  return(
   <button onClick={ this.toggle }> Toggle </button>
  {
    this.state.show ? (<div> HELLO </div>) : null
  }
   );
     }
Basitmir
quelle
Weitere Informationen zum Festlegen des Status "basierend auf dem vorherigen Status" finden Sie unter reactjs.org/docs/react-component.html#setstate . Auch wäre es schön, die Einrückung am Ende zu korrigieren.
Dan Dascalescu
0

Dieses Beispiel zeigt, wie Sie zwischen Komponenten wechseln können, indem Sie einen Schalter verwenden, der alle 1 Sekunde wechselt

import React ,{Fragment,Component} from "react";
import ReactDOM from "react-dom";

import "./styles.css";

const Component1 = () =>(
  <div>
    <img 
src="https://i.pinimg.com/originals/58/df/1d/58df1d8bf372ade04781b8d4b2549ee6.jpg" />
   </div>
)

const Component2 = () => {
  return (
    <div>
       <img 
src="http://www.chinabuddhismencyclopedia.com/en/images/thumb/2/2e/12ccse.jpg/250px- 
12ccse.jpg" />
  </div>
   )

 }

 class App extends Component {
   constructor(props) {
     super(props);
    this.state = { 
      toggleFlag:false
     }
   }
   timer=()=> {
    this.setState({toggleFlag:!this.state.toggleFlag})
  }
  componentDidMount() {
    setInterval(this.timer, 1000);
   }
  render(){
     let { toggleFlag} = this.state
    return (
      <Fragment>
        {toggleFlag ? <Component1 /> : <Component2 />}
       </Fragment>
    )
  }
}


const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Snivio
quelle
Was ist mit der seltsamen Bild-URL? Sie können einen Standard-Platzhalterdienst für Bilder
Dan Dascalescu,
0

Verwenden Sie diese schlanke und kurze Syntax:

{ this.state.show && <MyCustomComponent /> }
Zain Ul Hassan
quelle
Vielleicht könnten Sie Ihre Lean & Short-Syntax erweitern, um zu erklären, wie es funktioniert. Oh warte, das wurde in einer Antwort 3 Jahre zuvor gemacht . Was bringt Ihre Antwort wieder auf den Tisch?
Dan Dascalescu
0

Hier kommt die einfache, effektive und beste Lösung mit einer klassenlosen Reaktionskomponente zum Ein- und Ausblenden der Elemente. Verwendung von React-Hooks, die im neuesten Projekt zum Erstellen und Reagieren von Apps verfügbar sind , das React 16 verwendet

import React, {useState} from 'react';
function RenderPara(){
const [showDetail,setShowDetail] = useState(false);

const handleToggle = () => setShowDetail(!showDetail);

return (
<React.Fragment>
    <h3>
        Hiding some stuffs 
    </h3>
    <button onClick={handleToggle}>Toggle View</button>
   {showDetail && <p>
        There are lot of other stuffs too
    </p>}
</React.Fragment>)

}  
export default RenderPara;

Viel Spaß beim Codieren :)

Remi Prasanna
quelle
0
//use ternary condition

{ this.state.yourState ? <MyComponent /> : null } 

{ this.state.yourState && <MyComponent /> }

{ this.state.yourState == 'string' ? <MyComponent /> : ''}

{ this.state.yourState == 'string' && <MyComponent /> }

//Normal condition

if(this.state.yourState){
 return <MyComponent />
}else{
  return null;
}
Naved Khan
quelle
-1

Sie können die CSS-Datei verwenden

    var Results = React.createClass({
    render: function() {
        return (
            <div id="results" className={`search-results ${this.state.showResults ? 'show' : ''}`}>
                Some Results
            </div>
        );
    }
})

und in der CSS-Datei

    .search-results {
     ...
     display: none
     &.show {
      display: block
   }
}
arco
quelle
-1
var Search= React.createClass({
 getInitialState: () => { showResults: false },
 onClick: () => this.setState({ showResults: true }),
 render: function () {
   const { showResults } = this.state;
   return (
     <div className="date-range">
       <input type="submit" value="Search" onClick={this.handleClick} />
       {showResults && <Results />}
     </div>
   );
 }
});

var Results = React.createClass({
    render: function () {
        return (
            <div id="results" className="search-results">
                Some Results
            </div>
        );
    }
});

React.renderComponent(<Search /> , document.body);
Alan Paul Mathew
quelle
1
Können Sie erklären, was Sie getan haben und warum es besser ist als die akzeptierte Antwort?
Seblor
-1
class App extends React.Component {
  state = {
    show: true
  };

  showhide = () => {
    this.setState({ show: !this.state.show });
  };

  render() {
    return (
      <div className="App">
        {this.state.show && 
          <img src={logo} className="App-logo" alt="logo" />
        }
        <a onClick={this.showhide}>Show Hide</a>
      </div>
    );
  }
}
Mohammad Golkar
quelle
Können Sie bitte eine Erklärung zum besseren Verständnis hinzufügen? Vielen Dank!
Shanteshwar Inde
@ShanteshwarInde: Dies dupliziert dieselbe Idee aus einer vorherigen Antwort , einschließlich der falschen Verwendung von setState in Abhängigkeit vom aktuellen Status. Siehe reactjs.org/docs/react-component.html#setstate : "Wenn Sie den Status basierend auf dem vorherigen Status festlegen müssen, lesen Sie das Updater-Argument."
Dan Dascalescu
-1

var Search = React.createClass({
    getInitialState: function() {
        return { showResults: false };
    },
    onClick: function() {
        this.setState({ showResults: true });
    },
    render: function() {
        return (
            <div>
                <input type="checkbox" value="Search" onClick={this.onClick} />
                { this.state.showResults ? <Results /> : null }
            </div>
        );
    }
});

var Results = React.createClass({
    render: function() {
        return (
            <div id="results" className="search-results">
                <input type="text" />
            </div>
        );
    }
});

ReactDOM.render( <Search /> , document.getElementById('container'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.2/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/15.6.2/react-dom.min.js"></script>

<div id="container">
  <!-- This element's contents will be replaced with your component. -->
</div>

Venka
quelle
4
Während dieser Code die Frage möglicherweise beantwortet, verbessert die Bereitstellung eines zusätzlichen Kontexts darüber, warum und / oder wie dieser Code die Frage beantwortet, ihren langfristigen Wert.
Xiawi
Was @xiawi gesagt hat. Bitte verwenden Sie auch constanstelle von, varwenn Sie Konstanten deklarieren.
Dan Dascalescu