React文档(八)条件渲染

时间:2021-07-05 02:06:03

在React中,你可以创建不同的组件各自封装你需要的东西。之后你可以只渲染其中的一部分,这取决于应用的state(状态)。

条件渲染在React里就和js里的条件语句一样。使用js里的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里有很多方法来在行间使用条件,请往下面看相关介绍。

行内条件使用&&操作符

也许你会通过将表达式包在花括号里在JSX里嵌入表达式。这就包括了使用js里的&&操作符。这样可以很方便的来表示元素渲染的条件:

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')
);

在CodePen里试一试

在js里,true && expression的结果总会是expression,false && expression的结果总会是false。

因此,如果条件是true,在&&右边的元素就会在输出里。如果条件是false,React就会忽略它。

行内条件使用三目运算符

另外一个方法来条件渲染元素就是在行间使用js三目运算符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>
);
}

就像在js里一样,这取决于你选择一个合适的风格基于你和你的团队觉得哪一种可读性好。但也要记得无论何时状况变得太复杂,那最好去从中提取组件。

阻止组件渲染

有一些情况也许你希望一个组件隐藏起来即使它依靠别的组件渲染。想要隐藏它就返回null作为输出而不是渲染输出。

下面这个例子,<WarningBanner />依赖于prop的值warn来渲染。如果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将一直被调用。