在 React 中,你可以创建不同的组件来封装各种你需要的行为。然后还可以根据应用的状态变化只渲染其中的一部分。
React 中的条件渲染和 JavaScript 中的一致,使用 JavaScript 操作符 if 或条件运算符来创建表示当前状态的元素,然后让 React 根据它们来更新 UI。
元素变量
你可以使用变量来储存元素。它可以帮助你有条件的渲染组件的一部分,而输出的其他部分不会更改。
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
//文档学习
function UserGreeting(props) {
return <h1>Welcome back!</h1>;
}
function GuestGreeting(props) {
return <h1>Please sign up.</h1>;
}
function Greeting(props) {
const isLoggedIn = props.isLoggedIn;
if (isLoggedIn) {
return <UserGreeting />;
}
return <GuestGreeting />;
}
function LoginButton(props) {
return <button onClick={
props.onClick}>Login</button>;
}
function LogoutButton(props) {
return <button onClick={
props.onClick}>Logout</button>;
}
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"));
与运算符 &&
你可以通过用花括号包裹代码在** JSX 中嵌入任何表达式 **,也包括 JavaScript 的逻辑与 &&,它可以方便地条件渲染一个元素。
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
//文档学习
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 会忽略并跳过它。
三元运算符
条件渲染的另一种方法是使用 JavaScript 的条件运算符 condition ? true : false
。
在下面的例子中,我们用它来有条件的渲染一小段文本:
render() {
const isLoggedIn = this.state.isLoggedIn;
return (
<div>
The user is <b>{
isLoggedIn ? 'currently' : 'not'}</b> logged in.
</div>
);
}
完整代码
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
//文档学习
function UserGreeting(props) {
return <h1>Welcome back!</h1>;
}
function GuestGreeting(props) {
return <h1>Please sign up.</h1>;
}
function Greeting(props) {
const isLoggedIn = props.isLoggedIn;
if (isLoggedIn) {
return <UserGreeting />;
}
return <GuestGreeting />;
}
function LoginButton(props) {
return <button onClick={
props.onClick}>Login</button>;
}
function LogoutButton(props) {
return <button onClick={
props.onClick}>Logout</button>;
}
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>
<div>
The user is <b>{
isLoggedIn ? "currently" : "not"}</b> logged in.
</div>
<Greeting isLoggedIn={
isLoggedIn} />
{
button}
</div>
);
}
}
ReactDOM.render(<LoginControl />, document.getElementById("root"));
阻止组件渲染
在极少数情况下,你可能希望隐藏组件,即使它被其他组件渲染。让 render 方法返回 null 而不是它的渲染结果即可实现。
在下面的例子中,<WarningBanner />
根据属性 warn 的值条件渲染。如果 warn 的值是 false,则组件不会渲染:
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
//文档学习
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"));