条件渲染
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')
)