在React中,你可以创建囊括你需要的行为的明确的组件。而后,你根据应用的状态仅渲染组件中的一些。
在React中有条件的渲染同在JavaScript中条件使用一样。使用JavaScript操作符像if或者条件操作符创建代表当前状态的元素,让React把相应的他们更新到UI中。
考虑这两个组件:
function UserGreeting(props){
return <h1>Welcome back!</h1>
}
function GuestGreeting(props){
return <h1>Please sign up.</h1>
}
我们依据用户是否登录,创建展示这两个组件中的一个Greeting组件。
function Greeting(props){
const isLoggedIn=props.isLoggedIn;
if(isLoggedIn){
return <UserGreeting />;
}
return <GuestGreeting />;
}
ReactDOM.render(
//Try changing to isLoggedIn={true}
<Greeting isLoggedIn={false} />,
document.getElementById('root')
);
在CodePen上试试吧。
这个例子基于isLoggedIn属性值渲染不同的问候。
元素变量
你可以使用变量存储元素。这将帮你在输出的其他部分没有变化的情况下,有条件地渲染组件的一部分。
考虑表示退出和登陆按钮的这两个新组件:
function LoginButton(props){
return(
<button onClick={props.onClick}>
Login
</button>
);
}
function LogoutButton(props){
return(
<button onClick={props.onClick}>
Logout
</button>
);
}
在以下的例子中,我们将创建叫LoginControl的有状态的组件。
依赖它的当前状态,渲染<LoginButton />或者<LogoutButton />。它也渲染之前例子中的<Greeting />:
class LoginControl extends React.Component{
constructor(props){
super(props);
this.handleLoginClick=this.handleLoginClick.bind(this);
this.handleLogoutClick=this.handleLogoutClick.bind(this);
this.state={isLoggedIn:false};
}
handleLoginClick(){
this.setState({isLoggedIn:true});
}
handleLogoutClick(){
this.setState({isLoggedIn:false});
}
render(){
const isLoggedIn=this.state.isLoggedIn;
let button=null;
if(isLoggedIn){
button=<LogoutButton onClick={this.handleLogoutClick} />;
} else{
button=<LoginButton onClick={this.handleLoginClick}/>;
}
}
return{
<div>
<Greeting isLoggedIn={isLoggedIn} />
{button}
</div>
}
}
ReactDOM.render(
<LoginControl />,
document.getElementById('root')
);
在CodePen上试试吧。
声明变量和使用if语句是有条件地渲染组件的一个好的方法,有时你可能想用一个更短的语法。在JSX中有几个内敛条件的方法,如下所示:
逻辑&&运算符的内联if
在JSX中,你可以用大括号扩住表达式。包含逻辑&&运算符。有条件地包含一个元素很方便:
function Mailbox(props){
const unreadMessages=props.unreadMessages;
return(
<div>
<h1>Hello !</h1>
{unreadMessages.length>0 &&
<h2>
You have {unreadMessages.length} unread messages.
</h2>
}
</div>
);
}
const message=['React','Re:React','Re:Re:React'];
ReactDOM.render(
<Mailbox unreadMessages={messages} />,
document.getElementById('root')
);
在CodePen上试试吧。
这样写有效,是因为在JavaScript中,true&&expression 总会求expression的值,而false&&expression计算值总是false。
因此,如果条件正确,&&后的元素会出现在输出中。如果条件不正确,React将忽略并跳过它。
条件运算符的内联If-Else
有条件地渲染元素的另一个内联方法是使用JavaScript条件操作符condition ?true:false.
以下,我们用它有条件地渲染文本的一部分:
render(){
const isLoggedIn=this.state.isLoggedIn;
return(
<div>
The user is <b>{isLoggedIn?'currently':'not'}</b> logged in.
</div>
);
}
也可用在更大的表达式中,只是什么将执行就不怎么明确了:
render(){
const isLoggedIn=this.state.isLoggedIn;
return(
<div>
{isLoggedIn?(
<LogoutButton onClick={this.handleLogoutClick} />
):(
<LoginButton onClick={this.handleLoginClick} />
)}
</div>
);
}
像用JavaScript一样,选择什么更具可读性的合适的方式取决于你。还要记得条件变得很复杂是提取组件的好时机。
阻止组件渲染
在极少数情况下,尽管组件被另一个组件渲染,但是它需要隐藏自己。为了实现这样的效果,代替它的渲染输出返回null。
在以下例子中,<WarningBanner />基于warn属性值渲染。如果该属性值是false,那么组件不能渲染:
function WarningBanner(props){
if(!props.warn)
return null;
return(
<div className="warning">
Warning!
</div>
);
}
class Page extends React.Component{
constructor(props){
super(props);
this.state={showWarning:true}
this.handleToggleClick=this.handleToggleClick.bind(this);
}
handleToggleClick(){
this.setState(
prevState=>({showWarning:!prevState.showWarning})
);
}
render(){
return(
<div>
<WarningBanner warn={this.state.showWaring} />
<button onClick={this.handleToggleClick}>
{this.state.showWarning?'Hide':'Show'}
</button>
</div>
);
}
}
ReactDOM.render(
<Page />,
document.getElementById('root')
);
在CodePen中试试吧。
组件render方法返回null不影响组件生命周期方法的点燃。例如,componentWillUpdate和componentDidUpdate仍被调用。