רינדור מותנה
ב-React, אתם יכולים ליצור קומפוננטות יחודיות אשר מכמסות את ההתנהגות שאתם מחפשים. לאחר מכן, אתם יכולים לרנדר רק חלק מהן, על פי תלות ב-state של האפליקציה שלכם.
רינדור מותנה ב-React פועל באותו אופן שבו עובדים תנאים ב-JavaScript. השתמשו באופרטורים של JavaScript כמו if
או האופרטור המותנה כדי ליצור אלמנטים המייצגים את ה-state הנוכחי, ותנו ל-React לעדכן את ממשק המשתמש כדי שיהיה תואם אליהם.
הביטו בשתי הקומפוננטות האלו:
function UserGreeting(props) {
return <h1>ברוך הבא!</h1>;
}
function GuestGreeting(props) {
return <h1>אנא הירשם.</h1>;
}
ניצור קומפוננטת Greeting
שמציגה אחת מהקומפוננטות האלו כתלות באם משתמש מחובר:
function Greeting(props) {
const isLoggedIn = props.isLoggedIn;
if (isLoggedIn) { return <UserGreeting />; } return <GuestGreeting />;}
const root = ReactDOM.createRoot(document.getElementById('root'));
// Try changing to isLoggedIn={true}:
root.render(<Greeting isLoggedIn={false} />);
דוגמא זו מרנדרת ברכה שונה כתלות בערך של ה-prop isLoggedIn
.
משתני אלמנט
אתם יכולים להשתמש במשתנים כדי לשמור אלמנטים. זה יכול לעזור לכם לרנדר חלק מהקומפוננטה באופן מותנה בעוד ששאר הפלט אינו משתנה.
הביטו בשתי הקומפוננטות החדשות המייצגות כפתורי התנתקות והתחברות:
function LoginButton(props) {
return (
<button onClick={props.onClick}>
התחבר
</button>
);
}
function LogoutButton(props) {
return (
<button onClick={props.onClick}>
התנתק
</button>
);
}
בדוגמה הבאה, ניצור קומפוננטה התלויה ב-state שנקראת LoginControl
.
היא תרנדר <LoginButton />
או <LogoutButton />
כתלות ב-state הנוכחי שלה. בנוסף היא תרנדר <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>
);
}
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<LoginControl />);
בעוד שהכרזה על משתנה ושימוש בהצהרה if
היא דרך מצוינת להתנות רינדור קומפוננטה, לפעמים ייתכן שתרצו להשתמש בתחביר קצר יותר. ישנן מספר דרכים להטמיע תנאים ב-JSX, שמוסברות בהמשך.
הטמעת תנאי If עם אופרטור && לוגי
ביכולתכם להטמיע ביטויים ב-JSX על ידי עטיפתם בסוגריים מסולסלים. זה כולל את האופרטור הלוגי &&
של JavaScript. זה יכול להיות שימושי עבור הוספה מותנית של אלמנט:
function Mailbox(props) {
const unreadMessages = props.unreadMessages;
return (
<div>
<h1>Hello!</h1>
{unreadMessages.length > 0 && <h2> יש לך {unreadMessages.length} הודעות שלא נקראו. </h2> } </div>
);
}
const messages = ['React', 'Re: React', 'Re:Re: React'];
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Mailbox unreadMessages={messages} />);
זה עובד בגלל שב-JavaScript, true && expression
תמיד שווה ערך ל-expression
, ו-false && expression
תמיד שווה ערך ל-false
.
לכן, אם התנאי הוא true
, האלמנט מימין אחרי &&
יופיע בפלט. אם הוא false
, React תתעלם ממנו ותדלג עליו.
שים לב שהחזרת ביטוי שלילי עדיין תגרום לדילוג על האלמנט שאחרי &&
אבל עדיין תחזיר את הביטוי השלילי. בדוגמה להלן, <div>0</div>
יוחזר על ידי מתודת הרינדור.
render() {
const count = 0; return (
<div>
{count && <h1>Messages: {count}</h1>} </div>
);
}
הטמעת If-Else עם אופרטור ההתנייה
שיטה נוספת להטמעת רינדור אלמנטים מותנה היא להשתמש באופרטור ההתנייה של JavaScript condition ? true : false
.
בדוגמה הבאה, אנו משתמשים בו כדי לרנדר באופן מותנה בלוק קטן של טקסט.
render() {
const isLoggedIn = this.state.isLoggedIn;
return (
<div>
המשתמש <b>{isLoggedIn ? 'כרגע' : 'לא'}</b> מחובר. </div>
);
}
זה יכול לשמש גם עבור ביטויים גדולים יותר למרות שכך פחות ברור מה קורה:
render() {
const isLoggedIn = this.state.isLoggedIn;
return (
<div>
{isLoggedIn ? <LogoutButton onClick={this.handleLogoutClick} />
: <LoginButton onClick={this.handleLoginClick} /> }
</div> );
}
בדיוק כמו ב-JavaScript, זה באחריותכם לבחור סגנון מתאים על סמך מה שאתם והצוות שלכם מחשיבים יותר קריא. כמו כן זכרו שבכל פעם שתנאים נהיים מורכבים מדי, זה יכול להיות זמן טוב לחלץ קומפוננטה.
מניעת רינדור של קומפוננטה
במקרים נדירים ייתכן שתרצו שקומפוננטה תסתיר את עצמה למרות שהיא רונדרה על ידי קומפוננטה אחרת. כדי לעשות זאת החזירו null
במקום את הפלט שאותו היא אמורה לרנדר.
בדוגמה הבאה, ה-<WarningBanner />
מרונדר בהתאם לערך של ה-prop שנקרא warn
. אם ערך ה-prop הוא false
, אזי הרכיב אינו מתרנדר:
function WarningBanner(props) {
if (!props.warn) { return null; }
return (
<div className="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 ? 'הסתר' : 'הצג'}
</button>
</div>
);
}
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Page />);
החזרת null
ממתודת render
של קומפוננטה לא משפיעה על הרצת מתודות מחזור החיים של קומפוננטה. למשל componentDidUpdate
עדיין יקרא.