條件渲染
React沒有像v-if、v-show這樣的指令,需要使用JSX表達式組合而成
// 與運算 三目
// 判斷表達式一定是false/null/undefined時才不會被渲染,0、空字符串、NaN會顯示
// 如果render函數返回null,不會進行任何渲染
......state = {showLeft: false// showLeft: undefined, // 與運算中效果同false// showLeft: null, // 與運算中效果同false// showLeft: 0 // 在與運算中會顯示// showLeft: Number(undefined) // 在與運算中會顯示}
......{!this.state.showLeft && <Right />}
HTML中使用JSX
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script type="text/babel"> </script>
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><script crossorigin src="https://unpkg.com/react@17/umd/react.production.min.js"></script><script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script><script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script><title>React 條件渲染</title>
</head><body><div id="app"></div><script type="text/babel">class Left extends React.Component {render() {return (<div>Left</div>)}}class Right extends React.Component {render() {return (<div>Right</div>)}}class Main extends React.Component {state = {showLeft: false// showLeft: undefined, // 與運算中效果同false// showLeft: null, // 與運算中效果同false// showLeft: 0 // 在與運算中會顯示// showLeft: Number(undefined) // 在與運算中會顯示}handleClick() {this.setState({showLeft: !this.state.showLeft})}render() {return (<div><h1>Main</h1><button onClick={this.handleClick.bind(this)}>{this.state.showLeft ? 'turn Right' : 'turn Left'}</button>{// 1. 三目運算// this.state.showLeft ? <Left /> : <Right />}{// 2. 與運算this.state.showLeft && <Left />}{!this.state.showLeft && <Right />}</div>)}}ReactDOM.render(<Main />,document.getElementById('app'))</script></body></html>
列表渲染 JSX → map
table相關warning
JSX中使用table,若未加tbody、thead會告警
key相關warning
- Each child in a list should have a unique “key” prop.(列表中的每個子元素都必需有一個唯一的key屬性值)
- key是React確定元素是否改變的唯一標識,key必需在兄弟節點中是唯一的
不建議使用index作為key值的情況
- 建立在列表順序改變、元素增刪的情況下:列表增刪或順序變了,index對應項就會改變
- 若列表是靜態不可操作的,可以選擇index作為key值
- 用數據唯一的id作為key
- 動態生成一個靜態id
nanoid
yarn add nanoid
每次render都會生成不同的id
import { nanoid } from 'nanoid'
class MyTable extends React.Component {state = {table: [{id: 0,name: '漁'},{id: 1,name: '樵'},{id: 2,name: '耕'},{id: 3,name: '讀'},]}render() {return (<div><table border="1"><thead><tr><th>nanoid</th><th>ID</th><th>名字</th></tr></thead><tbody>{this.state.table.map(item => {const key = nanoid()return (<tr key={key}><td>{key}</td><td>{item.id}</td><td>{item.name}</td></tr>)})}</tbody></table></div>)}
}
ReactDOM.render(<MyTable />,document.getElementById('app')
)
key賦值的正確姿勢
- 注意:React明確規定,key不能作為屬性傳遞給子組件,必須顯示傳遞key值(使用別的屬性名,如sid)
- 防止開發者在邏輯中對key值進行操作
MyBody: key is not a prop. Trying to access it will result in
undefinedbeing returned. If you need to access the same value within the child component, you should pass it as a different prop.
import { nanoid } from 'nanoid'
class MyTitle extends React.Component {render() {return (<thead><tr><th>nanoid</th><th>ID</th><th>名字</th></tr></thead>)}
}
class MyBody extends React.Component {render() {// 這里constructor super都省略了const { sid, item } = this.propsreturn (<tr key={sid}><td>{sid}</td><td>{item.id}</td><td>{item.name}</td></tr>)}
}
class MyTable extends React.Component {state = {table: [{id: 0,name: '漁'},{id: 1,name: '樵'},{id: 2,name: '耕'},{id: 3,name: '讀'},]}render() {return (<div><table border="1"><MyTitle /><tbody>{this.state.table.map(item => {const key = nanoid()return (// 分別是傳入的2個props 以及自身組件循環時的key<MyBody sid={key} item={item} key={key} />)})}</tbody></table></div>)}
}
ReactDOM.render(<MyTable />,document.getElementById('app')
)