一、条件渲染
1、条件渲染
我们可以通过创建不同的组件封装不同的行为,然后根据应用的状态渲染对应状态下的部分内容
// 定义组件封装登陆行为 class SignIn extends React.Component { constructor(props) { super(props) } render() { return <h1>Please Sign In</h1> } } // 定义组件封装注册行为 class SignUp extends React.Component { constructor(props) { super(props) } render() { return <h1>Please Sign Up</h1> } } // 根据用户是否已经登陆决定渲染哪个组件 class Greeting extends React.Component { constructor(props) { super(props) } render() { if (this.props.isSignUp) { return <SignIn /> } else { return <SignUp /> } } } ReactDOM.render( <Greeting isSignUp={false} />, document.getElementById('app') );
2、阻止组件渲染
在某些情况下,我们希望可以隐藏元素,这时候我们需要让 render()
返回 null
即可
class Warning extends React.Component { constructor(props) { super(props) } render() { if (this.props.isWaring) { return <span>Waring!</span> } else { return null } } } ReactDOM.render( <Warning isWarning={false}/>, document.getElementById('app') );
3、元素变量
我们可以使用变量储存元素,使得我们可以有条件地渲染组件的一部分
class LoginControl extends React.Component { constructor(props) { // 1、传递 props super(props); // 2、初始 state this.state = {isLoggedIn: false}; // 3、为事件处理函数绑定组件实例 this.handleLoginClick = this.handleLoginClick.bind(this); this.handleLogoutClick = this.handleLogoutClick.bind(this); } handleLoginClick() { this.setState({isLoggedIn: true}); } handleLogoutClick() { this.setState({isLoggedIn: false}); } render() { // 使用变量根据条件储存元素 let greeting; let button; if (this.state.isLoggedIn) { greeting = <h1>Now you are logged in!</h1>; button = <button onClick={this.handleLogoutClick}>Log Out</button>; } else { greeting = <h1>Please log in!</h1>; button = <button onClick={this.handleLoginClick}>Log In</button>; } return ( <div> {greeting} {button} </div> ); } } ReactDOM.render( <LoginControl isLoggedIn={false} />, document.getElementById('app') );
二、列表渲染
1、渲染元素
在 React组件中,我们可以通过 map()
方法快速渲染列表元素,我们先来看一个小例子
<!DOCTYPE html> <html> <head> <title>Demo</title> <script src="https://unpkg.com/react@16/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> <script src="https://unpkg.com/babel-standalone"></script> </head> <body> <div id="app"></div> <script type="text/babel"> class ItemList extends React.Component { render() { const numbers = [1, 2, 3, 4, 5] const items = numbers.map((number)=>(<li>{ number }</li>)) return (<ul>{ items }</ul>) } } ReactDOM.render( <ItemList />, document.getElementById('app') ); </script> </body> </html>
2、key 属性
在上面的例子中,虽然可以正常显示元素,但是当我们打开控制台的时候,会看到有一条警告信息
Warning: Each child in a list should have a unique "key" prop.
我们可以通过给每个列表元素分配一个 key
属性来解决上面这个问题
class ItemList extends React.Component { render() { const numbers = [1, 2, 3, 4, 5] const items = numbers.map((number)=>( <li key={ number.toString() }> { number } </li> )) return ( <ul>{ items }</ul> ) } }
一个元素的 key 最好是这个元素在列表中拥有的独一无二的字符串,万不得已的情况下也可以使用元素索引
class ItemList extends React.Component { render() { const numbers = [1, 2, 3, 4, 5] const items = numbers.map((number, index)=>( <li key={ index }> { number } </li> )) return ( <ul>{ items }</ul> ) } }
如果列表项目的顺序会发生改变,那么不建议使用索引作为 key
因为这样可能会导致性能问题,甚至会引起组件状态的问题
在默认的情况下,即我们没有显式指定 key 时,React 将使用索引作为列表项目的 key
3、渲染组件
除了可以使用 map()
方法渲染多个元素,还可以使用 map()
渲染多个组件,请看一个例子
class TodoItem extends React.Component { constructor(props) { super(props) } render() { return ( <h3>{ this.props.title }</h3> ) } } class TodoList extends React.Component { constructor(props) { super(props) this.state = { itemList: [ {id: 0, title: 'Say Hello', isDone: true}, {id: 1, title: 'Say Goodbye', isDone: false} ] } } render() { const todoItemList = this.state.itemList.map((item) => { if (!item.isDone) { return ( <li key={ item.id }><TodoItem title={ item.title } /></li> ) } }) return ( <ul>{ todoItemList }</ul> ) } } ReactDOM.render( <TodoList />, document.getElementById('app') )