6.Conditional Rendering(條件渲染)

React版本:15.4.2
**翻譯:xiyoki **

在React中儿礼,你可以創(chuàng)建許多不同的組件指蚜,這些組件封裝了你所需要的行為献起。然后,你可以僅渲染其中的一些祷杈,具體取決于應(yīng)用程序的state斑司。
React中的條件渲染與Javascript中的條件的工作方式相同。使用Javascript操作符但汞,例如if或條件操作符來創(chuàng)建一個(gè)表示當(dāng)前state的元素宿刮,然后讓React匹配它們,并更新UI特占。
考慮這兩個(gè)組件:

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

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

我們將創(chuàng)建一個(gè)Greeting組件糙置,它的展現(xiàn)將取決于用戶是否登錄云茸。

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')
);

這個(gè)例子是目,根據(jù)isLoggedIn的屬性值渲染了不同的歡迎辭。

Element Variables(元素變量)

你可以使用變量來存儲元素标捺。這可以幫助你有條件地渲染組件的一部分懊纳,而組件其余的輸出不會改變揉抵。
考慮這兩個(gè)代表注銷和登錄按鈕的新組件:

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

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

在下面的例子中,我們將創(chuàng)建一個(gè)有state的組件嗤疯,叫LoginControl冤今。
它將根據(jù)其當(dāng)前的state渲染<LoginButton /><LogoutButton />中任意一個(gè)。它也會渲染來自前一個(gè)例子的<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 = null;
    if (isLoggedIn) {
      button = <LogoutButton onClick={this.handleLogoutClick} />;
    } else {
      button = <LoginButton onClick={this.handleLoginClick} />;
    }

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

雖然聲明一個(gè)變量戏罢,并且使用if語句來有條件地渲染組件是一個(gè)很好的方式,然而有時(shí)你可能需要使用更短的語法脚囊。有幾種在JSX中內(nèi)聯(lián)條件的方法龟糕,如下所述。

Inline If with Logical && Operator(使用邏輯&&運(yùn)算符內(nèi)聯(lián)if語句)

你可以在JSX中內(nèi)嵌任何用{}包裹的表達(dá)式悔耘。這包括Javascript中的邏輯&&運(yùn)算符讲岁。它可以很方便地有條件地包括一個(gè)元素:

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')
);

它之所以工作是因?yàn)樵贘avaScript中, true && expression 總是計(jì)算為expression, 而false && expression 總是計(jì)算為false
因此衬以,如果條件是true缓艳,那么剛好在&&符右邊的元素將會出現(xiàn)在輸出中。如果是false看峻,React會忽略并跳過它阶淘。

Inline If-Else with Conditional Operator(使用條件操作符內(nèi)聯(lián)if-else 語句)

在行內(nèi)有條件地渲染元素的另一種方法是使用Javascript的三元運(yùn)算符condition ? true : false
在下面的例子中互妓,我們使用它來有條件地渲染一小塊文本舶治。

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

它也可以用于較大的表達(dá)式,雖然發(fā)生了什么會不太明顯:

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

就像在Javascript中一樣车猬,你可以基于你和你的團(tuán)隊(duì)對可讀寫性的考慮霉猛,自主地選擇一個(gè)適當(dāng)?shù)娘L(fēng)格。 當(dāng)條件變得過于復(fù)雜時(shí)珠闰,不要忘了這可能是一個(gè)提取組件的好時(shí)機(jī)惜浅。

Preventing Component from Rendering(阻止組件渲染)

在極少的情況下,你可能希望組件隱藏自身伏嗜,即使它已由另一個(gè)組件渲染坛悉。通過返回null,而不是返回渲染輸出承绸,即可隱藏組件自身裸影。
在下面的例子中,<WarningBanner />的渲染依賴于warn屬性的值军熏,如果屬性值是false,那么組件將不會渲染轩猩。

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(prevState => ({
      showWarning: !prevState.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')
);

從組件的render方法中返回null,并不會影響組件生命周期方法的觸發(fā)。例如均践,componentWillUpdatecomponentDidUpdate 依然會被調(diào)用晤锹。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市彤委,隨后出現(xiàn)的幾起案子鞭铆,更是在濱河造成了極大的恐慌,老刑警劉巖焦影,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件车遂,死亡現(xiàn)場離奇詭異,居然都是意外死亡斯辰,警方通過查閱死者的電腦和手機(jī)艰额,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來椒涯,“玉大人柄沮,你說我怎么就攤上這事》掀瘢” “怎么了祖搓?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長湖苞。 經(jīng)常有香客問我拯欧,道長,這世上最難降的妖魔是什么财骨? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任镐作,我火速辦了婚禮,結(jié)果婚禮上隆箩,老公的妹妹穿的比我還像新娘该贾。我一直安慰自己,他們只是感情好捌臊,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布杨蛋。 她就那樣靜靜地躺著,像睡著了一般理澎。 火紅的嫁衣襯著肌膚如雪逞力。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天糠爬,我揣著相機(jī)與錄音寇荧,去河邊找鬼。 笑死执隧,一個(gè)胖子當(dāng)著我的面吹牛揩抡,可吹牛的內(nèi)容都是我干的户侥。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼捅膘,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了滚粟?” 一聲冷哼從身側(cè)響起寻仗,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎凡壤,沒想到半個(gè)月后署尤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡亚侠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年曹体,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片硝烂。...
    茶點(diǎn)故事閱讀 38,018評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡箕别,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出滞谢,到底是詐尸還是另有隱情串稀,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布狮杨,位于F島的核電站母截,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏橄教。R本人自食惡果不足惜清寇,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望护蝶。 院中可真熱鬧华烟,春花似錦、人聲如沸持灰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽搅方。三九已至比吭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間姨涡,已是汗流浹背衩藤。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留涛漂,地道東北人赏表。 一個(gè)月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓检诗,卻偏偏與公主長得像,于是被迫代替她去往敵國和親瓢剿。 傳聞我的和親對象是個(gè)殘疾皇子逢慌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 本筆記基于React官方文檔,當(dāng)前React版本號為15.4.0间狂。 1. 安裝 1.1 嘗試 開始之前可以先去co...
    Awey閱讀 7,649評論 14 128
  • 最近看了一本關(guān)于學(xué)習(xí)方法論的書攻泼,強(qiáng)調(diào)了記筆記和堅(jiān)持的重要性。這幾天也剛好在學(xué)習(xí)React鉴象,所以我打算每天堅(jiān)持一篇R...
    gaoer1938閱讀 1,666評論 0 5
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,501評論 25 707
  • 以下內(nèi)容是我在學(xué)習(xí)和研究React時(shí)忙菠,對React的特性、重點(diǎn)和注意事項(xiàng)的提取纺弊、精練和總結(jié)牛欢,可以做為React特性...
    科研者閱讀 8,219評論 2 21
  • 你會迷茫傍睹,是因?yàn)槟氵€有選擇雀哨。 等你無從選擇的時(shí)候叨襟,你連迷茫的機(jī)會都沒有了也糊。 ——音橙橙 1 上周末逛街色查,過紅綠燈的...
    厘月閱讀 455評論 0 1