React 條件渲染方法大全

使用 if else

import React from 'react'

interface Feed {
	name: string
	price: string
}

const FeedList: React.FunctionComponent<{ feeds: Feed[] }> = props => {
	const { feeds } = props

	if (feeds.length) {
		return <div>have no data</div>
	} else {
		return (
			<div> {feeds.map(item => ( <p> {item.name}:{item.price} </p> ))} </div>
		)
	}
}
複製代碼

使用 switch

const Content: React.FunctionComponent<any> = ()=> {
  const [style, setStyle] = useState<number>(0)

	return (
		<div> {(() => { switch (style) { case 1: return 'black' break case 2: return 'pink' break default: return 'white' } })()} </div>
	)
}
複製代碼

使用三元運算法

const FeedList: React.FunctionComponent<{ feeds: Feed[] }> = props => {
	const { feeds } = props

	return (
		<div> {feeds.length ? 'have no data' : feeds.map(item => ( <p> {item.name}:{item.price} </p> ))} </div>
	)
}
複製代碼

使用邏輯 && 運算法

當渲染不是非一即二的時候,而只是在某一狀況下渲染時,使用三元運算法就會出現 nullundefinedfalse、空字符串之類的值,這在我看來好像有點奇怪,有點沒必要要react

const UserInfo: React.FunctionComponent<InfoProps> = props => {
  const { name } = props

  return (
		<div> { name ? <p>name</p> : null } </div>
	)
}
複製代碼

這個時候或許使用邏輯運算符會是更好的選擇:git

const UserInfo: React.FunctionComponent<InfoProps> = props => {
	const { name } = props

	return (
		<div> { name && <p>name</p> } </div>
	)
}
複製代碼

使用枚舉

咱們常常使用js對象 key...value 的形式存儲內容,使用 . 操做符來取的相應的值(這是一種hash表),若是咱們將這個與 react component 結合就會發生奇妙的反應:github

const APP: React.FunctionComponent<any> = ()=> {
  const [type, setStyle] = useState<string>('noData')
	return (
		<div> { { networkError: <div>some error with your network</div>, noData: <div>have no data</div>, success: <div>have data</div> }[type] } </div>
	)
}
複製代碼

可能將這個 value 爲 React Component 的對象單獨抽出來或許更方便理解算法

const APP: React.FunctionComponent<any> = ()=> {
  const [type, setStyle] = useState<string>('noData')
  const content = {
    networkError: <div>some error with your network</div>,
    noData: <div>have no data</div>,
    success: <div>have data</div>
  }
	return (
		<div> {content[type]} </div>
	)
}
複製代碼

當我初次接觸到這種寫法的時候,最直觀的感受就是這就是 switch 的替代(alternate),這就是多種狀態下的優雅編程。express

可是,我很好奇,這是怎麼運行的,我在命令行中編寫相似的代碼:編程

{a: 12, b:13}['a']
複製代碼

如我所料,這應該會報錯,是一種語法錯誤:babel

那麼爲何在 jsx 中倒是能夠正確運行,why?編程語言

我思索再三,jsx 組件會被 babel 轉化爲 React.createElement 這類的函數,以下:函數

其實本質上咱們的枚舉值會成爲函數 React.createElement 的一個參數,那麼這個參數就會運行一次拿到表達式的返回值,那麼就是等於學習

({a: 12, b:13}['a'])
複製代碼

不出所料,這正常運行了,並拿到了相應的值。

這個形式很是相似於咱們初學 JavaScript 時的匿名自執行函數:

咱們還被告訴,若是咱們不關心函數返回值,咱們能夠在函數表達式上前加上一元操做符一樣生效,同理運用在咱們這裏一樣生效,雖然咱們這裏顯然須要拿到返回值,可是至少不報錯了:

why?僅僅是 JavaScript 解析器解析語法的規則?原諒我不是科班出身,對編程語言底層不瞭解,但我對此很是感興趣,若是有知道的同窗期待您能告訴緣由,或者告訴我應該學習什麼來獲取答案。

扯的有點遠了,可是記住,枚舉值是一種很是優秀的條件渲染模式。

使用高階組件

這是一個摘自 robinwieruch 博客的例子:

// HOC declaration
function withLoadingIndicator(Component) {
  return function EnhancedComponent({ isLoading, ...props }) {
    if (!isLoading) {
      return <Component { ...props } />;
    }

    return <div><p>Loading...</p></div>;
  };
}

// Usage
const ListWithLoadingIndicator = withLoadingIndicator(List);
<ListWithLoadingIndicator
  isLoading={props.isLoading}
  list={props.list}
/>
複製代碼

我對於高階組件用的很少,可是很明顯的一點就是若是你封裝了一個公共組件,那麼這種模式頗有用。

使用 do 表達式

do 表達式如今是在第一階段,倉庫在 github.com/tc39/propos… ,所以使用時須要添加相應的 babel plugin:@babel/plugin-proposal-do-expressions

這個插件最終會將其轉化爲三元操做符,以下:

以上就是我使用過的條件渲染方法,但願對你有用,歡迎補充~

最後是一個廣告貼,最近新開了一個分享技術的公衆號,歡迎你們關注👇

相關文章
相關標籤/搜索