在React中 ,你可以创建封装了你所需要行为的不同组件,接着,你也能根据应用的状态,来选择渲染这些组件的部分行为。
根据条件渲染在React中的工作方式类似JavaScript。用JavaScript的操作符像:if或条件运算符来创造一些表征当前状态的元素,从而更新相关UI界面。
看看这两个组件:
function UserGreeting(props) {
return <h1>Welcome back!</h1>;
}
function GuestGreeting(props) {
return <h1>Please sign up.</h1>;
}
我们创建了这个‘greeting’组件,是呈现UserGreeting还是呈现GuestGreeting取决于用户的登录状态:
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')
);
这个例子渲染了不同的‘greeting’,根据的就是isLoggedIn这个属性的值。
元素变量
你可以用变量来储存一个元素。这样在组件中那些不需要变更的部分维持现状是,能帮助你条件性渲染组件(需要变更)的部分。
看看这两个新的组件,Logout登出和Login登入按钮:
function LoginButton(props) {
return (
<button onClick={props.onClick}>
Login
</button>
);
}
function LogoutButton(props) {
return (
<button onClick={props.onClick}>
Logout
</button>
);
}
接着我们创建一个‘状态满满’的组件:LoginControl。
该组件会渲染和当中的一个,渲染谁取决于当前它的状态。它也渲染了之前的例子组件:
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')
);
声明一个变量而且使用if语句是一个不错的方法来达到条件化渲染组件的目的,有时候你可能想用更简短的语法。下面介绍下载JSX中的行内条件判断。
行内的IF和逻辑&&操作符
任何JSX只要写在花括号里都是可嵌入的。这里面包括了JavaScript的’&&’(且运算符) 。这对于行内条件元素可能比较方便:
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 messages = ['React', 'Re: React', 'Re:Re: React'];
ReactDOM.render(
<Mailbox unreadMessages={messages} />,
document.getElementById('root')
);
这样之所以奏效,是因为在JavaScript中,true && 表达式 ,值永远等于表达式,且false && 表达式 永远等于false。
因此,要是条件的值是true(成立),那么&&右边的元素就会被输出;条件不成立,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,选哪一种风格是取决于你和你的团队认为哪一种风格可读性强,这由你决定。但也要记得,任何时候,条件太多太复杂,那么这时候就是提取组件的好时机。
防止组件渲染
少数情况下,你可能想要组件吧自己隐藏,即使组件本身被其他组件渲染着。这样你需要return null 来替代组件本身的输出。
下面的例子中,被渲染与否决定于一个叫warn属性props。如果这个prop属性值为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.showWarning} />
<button onClick={this.handleToggleClick}>
{this.state.showWarning ? 'Hide' : 'Show'}
</button>
</div>
);
}
}
ReactDOM.render(
<Page />,
document.getElementById('root')
);
从一个组件的render的方法返回null不会影响第一个生命周期方法。举例来说,componentWillUpdate和componentDidUpdate依然会被调用。