Ich mache zum ersten Mal etwas mit React.js zu tun und kann keine Möglichkeit finden, etwas auf einer Seite per Click-Ereignis anzuzeigen oder auszublenden. Ich lade keine anderen Bibliotheken auf die Seite, also suche ich nach einem nativen Weg mit der React-Bibliothek. Das habe ich bis jetzt. 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);
Der Schlüssel besteht darin, den Status der Komponente im Click-Handler mithilfe von setState
zu aktualisieren. Wenn die Statusänderungen angewendet werden, wird die render
-Methode erneut mit dem neuen Status 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'));
<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>
);
}
Hier ist eine alternative Syntax für den ternären Operator:
{ this.state.showMyComponent ? <MyComponent /> : null }
ist äquivalent zu:
{ this.state.showMyComponent && <MyComponent /> }
Auch alternative Syntax mit display: 'none';
<MyComponent style={this.state.showMyComponent ? {} : { display: 'none' }} />
Wenn Sie jedoch display: 'none'
zu stark verwenden, führt dies zu einer DOM-Verschmutzung und verlangsamt Ihre Anwendung.
Hier ist mein Ansatz mit ES6. Die akzeptierte Antwort ist zwar korrekt, aber ziemlich veraltet.
import React, { Component } from 'react';
// you should use ReactDOM.render instad of React.renderComponent
import ReactDOM from 'react-dom';
class ToggleBox extends Component {
constructor(props) {
super(props);
this.state = {
// toggle box is closed initially
isOpened: false,
};
// http://egorsmirnov.me/2015/08/16/react-and-es6-part3.html
this.toggleBox = this.toggleBox.bind(this);
}
toggleBox() {
this.setState(oldState => ({ isOpened: !oldState.isOpened }));
}
render() {
const { title, children } = this.props;
const { isOpened } = this.state;
return (
<div className="box">
<div className="boxTitle" onClick={this.toggleBox}>
{title}
</div>
{isOpened && children && (
<div className="boxContent">
{children}
</div>
)}
</div>
);
}
}
ReactDOM.render((
<ToggleBox title="Click me">
<div>Some content</div>
</ToggleBox>
), document.getElementById('app'));
Demo: http://jsfiddle.net/kb3gN/16688/
Es ist besser, ein Element nur dann zu rendern, wenn es benötigt wird, anstatt einige CSS-Klassen mit display: none
hinzuzufügen. Wenn Sie display: none
setzen, wird das Element immer noch durch das Reagieren gerendert und zu DOM
hinzugefügt.
Stellen Sie sich vor, Sie haben eine Seite mit Registerkarten, auf denen jede Registerkarte viel Inhalt hat und auf der nur eine Registerkarte geöffnet ist. Es ist viel besser, in der DOM
nur die Elemente zu halten, die angezeigt werden sollen.
Um dies zu erreichen, verwende ich im obigen Code folgenden Code:
{opened && <SomeElement />}
Das wird SomeElement
nur dann wiedergeben, wenn opened
wahr ist. Dies 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
mit der neuesten Version von 0.11 können Sie auch null zurückgeben, um keinen Inhalt anzuzeigen.
https://facebook.github.io/react/blog/2014/07/13/react-v0.11-rc1.html#rendering-to-null
Ich habe eine kleine Komponente erstellt, die dies für Sie erledigt: https://www.npmjs.com/package/react-toggle-display
Er setzt das style-Attribut auf display: none !important
basierend auf den Requisiten hide
oder show
.
Verwendungsbeispiel:
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);
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>
Es gibt bereits einige großartige Antworten, aber ich glaube nicht, dass sie sehr gut erklärt wurden, und einige der angegebenen Methoden enthalten einige Tricks, die die Leute stürzen könnten. Ich werde die drei Hauptwege (plus eine Off-Topic-Option) durchgehen, um dies zu tun und die Vor- und Nachteile zu erläutern. Ich schreibe das meistens, weil Option 1 viel empfohlen wurde und es viele Probleme mit dieser Option gibt, wenn sie nicht korrekt verwendet werden.
Diese Methode gefällt mir nicht, wenn Sie die Komponente nur einmal rendern und dort belassen. Das Problem ist, dass die Komponente jedes Mal, wenn Sie die Sichtbarkeit umschalten, neu erstellt wird. Dies 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 Klicken der 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 schnell beim Erstellen von Komponenten. Allerdings muss Ihr Code bei der Erstellung noch aufgerufen werden. Wenn der Code Ihres Konstruktors, ComponentDidMount, Rendering usw. teuer ist, wird die Anzeige der Komponente erheblich langsamer. Dies bedeutet auch, dass Sie dies nicht mit stateful-Komponenten verwenden können, bei denen der Zustand beibehalten werden soll, wenn er ausgeblendet ist (und wiederhergestellt wird, wenn er angezeigt wird.) Der einzige Vorteil ist, dass die verborgene Komponente erst erstellt wird, wenn sie ausgewählt ist. Verdeckte Komponenten verzögern also nicht das Laden der ersten 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.
Dadurch werden beide Komponenten einmal erstellt. Dann schließt der 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 nun die Initialisierungslogik schnell ist und die untergeordneten Objekte zustandslos sind, werden Sie keinen Unterschied in Bezug auf Leistung oder Funktionalität feststellen. Warum sollte React trotzdem eine brandneue Komponente erstellen? Wenn die Initialisierung jedoch teuer ist, wird sie von Option 1 jedes Mal ausgeführt, wenn Sie eine Komponente umschalten, wodurch die Seite beim Wechseln abgebremst wird. Option 2 führt beim Laden der ersten Seite alle Elemente der Komponente aus. Verlangsamung der ersten Ladung. Sollte noch einmal beachten. Wenn Sie die Komponente nur einmal basierend auf einer Bedingung anzeigen lassen 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 teuren Code in einer Lebenszyklusmethode haben. Dies ist im Allgemeinen keine gute Idee. Sie können und sollten möglicherweise das langsame Laden der Seite lösen, indem Sie den teuren Code aus den Lebenszyklusmethoden heraus verschieben. Verschieben Sie es in eine Async-Funktion, die von ComponentDidMount gestartet wurde, und lassen Sie den Callback mit setState () in eine Statusvariable schreiben. Wenn die Zustandsvariable null ist und die Komponente sichtbar ist, muss die Renderfunktion einen Platzhalter zurückgeben. Andernfalls die Daten rendern. 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 Kinder übertragen. Auf diese Weise können Sie priorisieren, welche Tabs zuerst geladen werden. Oder zwischenspeichern Sie die Ergebnisse und führen Sie die Logik nur beim ersten Anzeigen einer Komponente aus.
Klassenverstecken ist wahrscheinlich am einfachsten zu implementieren. Wie bereits erwähnt, erstellen Sie einfach eine CSS-Klasse mit display: none und ordnen die Klasse auf Basis von 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 keine verborgenen Komponenten. Bei Option 2 wird unnötiger Code kurzgeschlossen, wenn die Komponente ausgeblendet wird und die Komponente vollständig aus dem DOM entfernt wird.) Es scheint, dass die Sichtbarkeit bei einigen Tests, die von Kommentatoren durchgeführt werden, schneller ist andere Antworten, aber ich kann nicht dazu sprechen.
Diese Anwendung funktioniert nicht für jede Anwendung. Das Thema ist nicht verfügbar, da es nicht um das Ausblenden von Komponenten geht. Es kann jedoch in einigen Anwendungsfällen eine bessere Lösung sein als das Ausblenden. Nehmen wir an, Sie haben Registerkarten. Es kann möglich sein, eine React-Komponente zu schreiben und einfach die Requisiten zu verwenden, um die Anzeige auf der Registerkarte zu ändern. Sie können den JSX auch für Zustandsvariablen speichern und mithilfe einer Requisite entscheiden, welcher JSX in der Renderfunktion zurückgegeben werden soll. Wenn der JSX generiert werden muss, führen Sie ihn aus, zwischenspeichern Sie ihn in den übergeordneten Ordner und senden Sie den richtigen als Requisite. Oder generieren Sie es im Kind und zwischenspeichern Sie es im Zustand des Kindes und verwenden Sie Requisiten, um das aktive auszuwählen.
Dies ist eine nette Möglichkeit, das virtuelle DOM zu nutzen:
Reagieren:
var Comp = React.createClass({
getInitialState: function(){
return {hide: false};
},
toggle: function(){
this.setState({hide: !this.state.hide});
},
render: function() {
return <div>
<button onClick={this.toggle}>toggle</button>
<div className={'hide-' + this.state.hide}>Hi there</div>
</div>;
}
});
ReactDOM.render(
<Comp />,
document.getElementById('container')
);
CSS
.hide-true {
display: none;
}
Geige hier
Die folgende Vorgehensweise wird anhand der Dokumentation empfohlen:
{this.state.showFooter && <Footer />}
Rendern Sie das Element nur, wenn der Status gültig ist.
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>
);
}
}
Wenn Sie sehen möchten, wie die Anzeige einer Komponente umgeschaltet wird, ü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'));
In einigen Fällen kann eine Komponente höherer Ordnung nützlich sein:
Erstellen Sie eine Komponente höherer Ordnung:
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 kannst du es so benutzen:
<MyComp hidden={true} ... />
<MyComp shouldHide={this.props.useSomeFunctionHere} ... />
Dies reduziert etwas die Boilerplate und erzwingt das Festhalten an Namenskonventionen. Beachten Sie jedoch, dass MyComp immer noch instanziiert wird.
{ !hidden && <MyComp ... /> }
Ich beginne mit dieser Aussage des React-Teams:
In React können Sie unterschiedliche Komponenten erstellen, die das Verhalten einkapseln du brauchst. Sie können dann je nach .__ nur einige davon rendern. Status Ihrer Bewerbung.
Bedingtes Rendern in React funktioniert genauso wie Bedingungen in JavaScript. Verwenden Sie JavaScript-Operatoren wie if oder die Bedingung Operator, um Elemente zu erstellen, die den aktuellen Status darstellen, und lassen Sie Reagieren Sie die Benutzeroberfläche, um sie anzupassen.
Sie müssen die Komponente grundsätzlich anzeigen, wenn die Schaltfläche angeklickt wird. Sie haben zwei Möglichkeiten, reines Reagieren oder CSS zu verwenden, reines React-Verfahren. In Ihrem Fall können Sie so etwas wie den folgenden Code ausführen werden nicht angezeigt, da hideResults
ist true
, aber wenn Sie auf die Schaltfläche klicken, wird der Status geändert, und hideResults
ist false
und die Komponente wird mit den neuen Wertbedingungen erneut gerendert. Dies ist sehr üblich, wenn Sie die Komponentensicht in React ändern.
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 in Conduct weitere Untersuchungen zum bedingten Rendern durchführen möchten, schauen Sie nach hier .
Verwenden Sie diese schlanke und kurze Syntax:
{ this.state.show && <MyCustomComponent /> }
Verwenden Sie ref und manipulieren Sie CSS
Eine Möglichkeit könnte darin bestehen, Reacts ref
zu verwenden und die CSS-Klasse mit der API des Browsers zu bearbeiten. Es hat den Vorteil, dass das erneute Rendern in React vermieden wird, 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 Korrigiere mich, wenn ich mich irre.:)
Dies kann auch auf diese Weise 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
}
);
}
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
}
}
dieses Beispiel zeigt, wie Sie zwischen Komponenten wechseln können, indem Sie einen Umschalter 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);
Wenn Sie Bootstrap 4 verwenden, können Sie das Element auf diese Weise ausblenden
className={this.state.hideElement ? "invisible" : "visible"}
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);
Verwenden Sie rc-if-else module
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>
);
}
}