Υπό συνθήκες Rendering

Στο React, μπορείτε να δημιουργήσετε ξεχωριστά components που ενσωματώνουν τη συμπεριφορά που χρειάζεστε. Στη συνέχεια, μπορείτε να κάνετε render μόνο μαερικά από αυτά, ανάλογα με το state της εφαρμογής σας.

Το rendering υπό συνθήκες στο React λειτουργεί με τον ίδιο τρόπο που λειτουργούν οι συνθήκες στη JavaScript. Χρησιμοποιήστε τα JavaScript operators όπως το if ή το conditional operator για να δημιουργήσετε components που αντιπροσωπεύουν το τρέχον state και αφήστε το React να ενημερώσει το UI για να τα ταιριάξει.

Εξετάστε αυτά τα δύο components:

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

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

Θα δημιουργήσουμε ένα Greeting component που εμφανίζει ένα από τα παραπάνω components ανάλογα με το αν ένας χρήστης είναι συνδεδεμένος ή οχι:

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

ReactDOM.render(
  // Try changing to isLoggedIn={true}:
  <Greeting isLoggedIn={false} />,
  document.getElementById('root')
);

Δοκιμάστε το στο CodePen

Αυτό το παράδειγμα εμφανίζει διαφορετικό χαιρετισμό ανάλογα με την τιμή του isLoggedIn prop.

Μεταβλητές στοιχείων

Μπορείτε να χρησιμοποιήσετε μεταβλητές για την αποθήκευση στοιχείων. Αυτό μπορεί να σας βοηθήσει να κάνετε render υπό συνθήκες ένα μέρος του component ενώ το υπόλοιπο output δεν αλλάζει.

Εξετάστε αυτά τα δύο νέα components που αντιπροσωπεύουν τα κουμπιά Logout και Login:

function LoginButton(props) {
  return (
    <button onClick={props.onClick}>
      Login
    </button>
  );
}

function LogoutButton(props) {
  return (
    <button onClick={props.onClick}>
      Logout
    </button>
  );
}

Στο παρακάτω παράδειγμα, θα δημιουργήσουμε ένα stateful component που ονομάζεται LoginControl.

Αυτό θα κάνει render είτε το <LoginButton /> είτε το <LogoutButton /> ανάλογα με το τρέχον state του. Επίσης θα κάνει render ένα <Greeting /> από το προηγούμενο παράδειγμα:

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;

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

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

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

Δοκιμάστε το στο CodePen

Ενώ δηλώνεται μια μεταβλητή και χρησιμοποιείτε μια εντολή if είναι ένας καλός τρόπος για την υπό συνθήκη render ενός component, μερικές φορές μπορεί να θέλετε να χρησιμοποιήσετε μια σύντομη σύνταξη. Υπάρχουν μερικοί τρόποι για να εισάγετε τις συνθήκες στο JSX, που εξηγείται παρακάτω.

If σε μια γραμμή με το λογικό Οperator &&

Μπορείτε να ενσωματώσετε οποιεσδήποτε εκφράσεις μέσα στο JSX περικλείοντας τα σε άγκιστρα. Αυτό περιλαμβάνει τον λογικό operator της JavaScript &&. Μπορεί να είναι βολικό για να συμπεριλάβει υπό συνθήκη ένα component:

function Mailbox(props) {
  const unreadMessages = props.unreadMessages;
  return (
    <div>
      <h1>Hello!</h1>
      {unreadMessages.length > 0 &&
        <h2>
          You have {unreadMessages.length} unread messages.
        </h2>
      }
    </div>
  );
}

const messages = ['React', 'Re: React', 'Re:Re: React'];
ReactDOM.render(
  <Mailbox unreadMessages={messages} />,
  document.getElementById('root')
);

Δοκιμάστε το στο CodePen

Λειτουργεί επειδή στην JavaScript, το true && expression πάντα αποτιμάται σε expression, και το false && expression πάντα αποτιμάται σε false.

Επομένως, αν η κατάσταση είναι true, το component αμέσως μετά το && θα εμφανιστεί στο output. Εάν είναι false, το React θα το αγνοήσει.

Inline If-Else with Conditional Operator

Μια άλλη μέθοδος για να κάνετε rendering υπό συνθήκες τα components σε μια γραμμή, είναι η χρήση του conditional operator στη JavaScript condition ? true : false.

Στο παρακάτω παράδειγμα, το χρησιμοποιούμε για να κάνουμε render υπό συνθήκες ένα μικρό κομμάτι κειμένου.

render() {
  const isLoggedIn = this.state.isLoggedIn;
  return (
    <div>
      The user is <b>{isLoggedIn ? 'currently' : 'not'}</b> logged in.
    </div>
  );
}

Μπορεί επίσης να χρησιμοποιηθεί για μεγαλύτερες εκφράσεις, αν και είναι λιγότερο προφανές τι συμβαίνει:

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

Όπως και στη JavaScript, εξαρτάται από εσάς να επιλέξετε ένα κατάλληλο στυλ με βάση αυτό που εσείς και η ομάδα σας θεωρείτε πιο ευανάγνωστο. Επίσης, να θυμάστε ότι όταν οι συνθήκες είναι υπερβολικά περίπλοκες, ίσως είναι καλή στιγμή να εξάγετε ένα component.

Αποτρέψτε το Component από το Rendering

Σε σπάνιες περιπτώσεις μπορεί να θέλετε ένα component να μην εμφανίζεται, ακόμα και αν έχει γίνει render από ένα άλλο component. Για να το κάνετε αυτό, επιστρέψτε null αντί της κανονικής του εμφάνισης.

Στο παρακάτω παράδειγμα, το <WarningBanner /> θα εμφανιστεί ανάλογα με την τιμή του prop που ονομάζεται warn. Εάν η τιμή του prop είναι false, τότε το component δεν θα εμφανιστεί:

function WarningBanner(props) {
  if (!props.warn) {
    return null;
  }

  return (
    <div className="warning">
      Warning!
    </div>
  );
}

class Page extends React.Component {
  constructor(props) {
    super(props);
    this.state = {showWarning: true};
    this.handleToggleClick = this.handleToggleClick.bind(this);
  }

  handleToggleClick() {
    this.setState(state => ({
      showWarning: !state.showWarning
    }));
  }

  render() {
    return (
      <div>
        <WarningBanner warn={this.state.showWarning} />
        <button onClick={this.handleToggleClick}>
          {this.state.showWarning ? 'Hide' : 'Show'}
        </button>
      </div>
    );
  }
}

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

Δοκιμάστε το στο CodePen

Επιστρέφοντας null απο την μέθοδο render του component, δεν επηρεάζει την ενεργοποίηση των μεθόδων του κύκλου ζωής του component. Για παράδειγμα το componentDidUpdate θα εξακολουθεί να καλείτε.