条件渲染
在 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(
// 修改为 isLoggedIn={true} 试试:
<Greeting isLoggedIn={false} />,
document.getElementById('root')
);
这个例子根据 isLoggedIn
prop 渲染了不同的问候语 。
元素变量
你可以用变量来存储元素。这可以帮助您有条件地渲染组件的一部分,而输出的其余部分不会更改。
思考以下两个新组件,分别用于显示登出和登入按钮:
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;
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 && expression
总是会评估为 expression
,而 false && expression
总是执行为 false
。
因此,如果条件为 true
,则 &&
后面的元素将显示在输出中。 如果是 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
而不是其渲染输出。
在下面的例子中,根据名为warn
的 prop 值,呈现 <WarningBanner />
。如果 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
仍将被调用。