I. Conditional Rendering
1. Conditional Rendering
In React, we can encapsulate different behaviors by creating different components, and then render parts of the corresponding state according to the state of the application.
// Define component encapsulation login behavior class SignIn extends React.Component { constructor(props) { super(props) } render() { return <h1>Please Sign In</h1> } } // Define component encapsulation registration behavior class SignUp extends React.Component { constructor(props) { super(props) } render() { return <h1>Please Sign Up</h1> } } // Decide which component to render based on whether the user has logged in or not 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. Blocking Component Rendering
In some cases, we want to hide elements, and we need render() to return 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. Elemental variables
We can use variables to store elements so that we can conditionally render parts of components.
class LoginControl extends React.Component { constructor(props) { // 1. Transfer props super(props); // 2. Initial state this.state = {isLoggedIn: false}; // 3. Binding component instances for event handlers this.handleLoginClick = this.handleLoginClick.bind(this); this.handleLogoutClick = this.handleLogoutClick.bind(this); } handleLoginClick() { this.setState({isLoggedIn: true}); } handleLogoutClick() { this.setState({isLoggedIn: false}); } render() { // Use variables to store elements conditionally 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') );
List Rendering
1. Rendering Elements
In React components, we can quickly render list elements by map(). Let's start with a small example.
<!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 attribute
In the example above, although elements can be displayed normally, when we open the console, we see a warning message.
visual basic Warning: Each child in a list should have a unique "key" prop.
We can solve this problem by assigning a key attribute to each list element.
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> ) } }
The key of an element is best a unique string that the element has in the list and can be indexed by the element if necessary.
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> ) } }
If the order of list items changes, it is not recommended to use indexes as key s, as this may lead to performance problems or even component state problems.
By default, when we do not explicitly specify the key, React uses the index as the key of the list item.
3. Rendering Component
In addition to using the map() method to render multiple elements, you can also use map() to render multiple components. See an example.
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') )
[Read more React articles, see React Learning Notes ]