如何在JSX中嵌入表达式

109 阅读5分钟

JSX是对JavaScript语言的扩展,因此它可以接受任何放在大括号内的有效JavaScript表达式。例如,4 + 4,user.firstName,或 formatName(user)都是有效的JavaScript表达式。这使你可以使你的JSX更加动态。在本教程中,我们将看看在JJSX标记中嵌入表达式的一些其他例子,以及在JJSX表达式中呈现一个以上的html标签的一些相关规则。我们将看到需要一个父元素,并学习一些方法来确保我们满足这一要求。


从一个新的应用程序开始

多亏了Create React App,我们可以非常容易地开发一个新的应用程序,这正是我们现在要做的。我们将它命名为cartable,因为我们想大致了解购物车在React中的工作原理。

react $create-react-app cartable
Creating a new React app in C:nodereactcartable.

用React安装Bootstrap

现在,我们要添加Bootstrap,使用户界面看起来更漂亮。因此,首先,在终端我们要像这样简单地安装最新版本的Bootstrap。

cartable $npm install bootstrap

+ bootstrap@4.3.1
added 1 package from 2 contributors and audited 36233 packages in 35.67s

为了使用Bootstrap,我们现在需要在index.js文件中导入它,就像我们在这里看到的。
index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import 'bootstrap/dist/css/bootstrap.css';

ReactDOM.render(<App />, document.getElementById('root'));

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();

创建一个组件文件夹

我们将在这个项目中添加不止一个组件,所以创建一个文件夹来存放我们需要的组件是有意义的。在这里,我们可以创建一个新的文件夹,在 **src**文件夹,命名为 components.
react components folder

在该组件文件夹中,让我们添加一个新的文件,代表购物车中的一个项目。这就是item.jsx文件。
item.jsx
item-jsx in components folder

现在只需向该文件添加一些简单的JSX标记。它是一个单一的h1标签,文本是Cartable!

import React, { Component } from "react";

class Item extends Component {
  render() {
    return <h1>Cartable!</h1>;
  }
}

export default Item;

让我们把这个组件添加到index.js文件中,以便它能在页面上呈现。请注意,我们正在删除默认的渲染,并将其替换为。
index.js

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import * as serviceWorker from "./serviceWorker";
import "bootstrap/dist/css/bootstrap.css";
import Item from "./components/item";

ReactDOM.render(<Item />, document.getElementById("root"));

serviceWorker.unregister();

在index.html文件中,由于我们已经安装了Bootstrap,我们可以给body元素添加一个类。这将在页面上很好地拉开空间。

容器是Bootstrap中最基本的布局元素,在使用我们的默认网格系统时需要。可以选择响应式的、固定宽度的容器(意味着它的最大宽度在每个断点处都会改变)或流体宽度(意味着它一直都是100%的宽度)。

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, shrink-to-fit=no"
    />
    <meta name="theme-color" content="#000000" />

    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />

    <title>React App</title>
  </head>
  <body class="container">
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
  </body>
</html>

好了,我们上路了!
react element rendered on the page


JSX中的表达式

你可以有一个以上的标签作为JSX表达式的一部分。到目前为止,我们只看到一个h1标签,但如果我们想在同一个JSX表达式中同时有一个h1和一个按钮呢。为了使其正常工作,我们需要一个外层包装的div。JSX表达式必须有一个父元素。此外,最好的做法是用小括号**( );**包裹整个JSX表达式。
item.jsx

import React, { Component } from "react";

class Item extends Component {
  render() {
    return (
      <div>
        <h1>Cartable!</h1>
        <button>Increment</button>
      </div>
    );
  }
}

export default Item;

embedded react expression


React.Fragment

你可能不希望用过多的div元素污染你的HTML标记。在上面的例子中,我们需要用一个单一的父元素来包裹h1和按钮标签。这是JSX的一个规则。然而,缺点是,如果我们检查页面上的标记,你会发现现在多了一个div元素。
extra div in react markup

我们可以通过使用<React.Fragment>标签代替

元素来解决这个额外的div问题。

import React, { Component } from "react";

class Item extends Component {
  render() {
    return (
      <React.Fragment>
        <h1>Cartable!</h1>
        <button>Increment</button>
      </React.Fragment>
    );
  }
}

export default Item;

react fragment removes extra divs


为组件添加状态

现在,我们可以使用一些数据,而不是在JSX表达式中的静态内容,从 **state**对象来显示一个值。在下面这个片段中,我们将该状态对象的属性添加为 count.它的值是0。为了在JJSX标记中引用该计数,我们使用this.state.count

import React, { Component } from "react";

class Item extends Component {
  state = {
    count: 0
  };
  
  render() {
    return (
      <React.Fragment>
        <span>{this.state.count}</span>
        <button>Increment</button>
      </React.Fragment>
    );
  }
}

export default Item;

输出显示的是我们为count属性设置的值。
ui updates from state

如果我们改变count属性的值,那么UI就会自动更新。

import React, { Component } from "react";

class Item extends Component {
  state = {
    count: 400
  };

  render() {
    return (
      <React.Fragment>
        <span>{this.state.count}</span>
        <button>Increment</button>
      </React.Fragment>
    );
  }
}

export default Item;

react state object update


嵌入一个函数

也可以在JSX标记中嵌入一个返回值的函数。在我们下面的Item组件中,我们添加了一个styleCount()函数。这个函数的工作是查看计数状态,如果它是0,则返回字符串值 "No Items"。如果该值大于0,那么它就简单地返回该值。在JJSX标记中,我们可以用{this.styleCount()}的语法来使用这个函数,它可以输出这个函数返回的任何值。

import React, { Component } from "react";

class Item extends Component {
  state = {
    count: 0
  };

  render() {
    return (
      <React.Fragment>
        <span>{this.styleCount()}</span>
        <button>Increment</button>
      </React.Fragment>
    );
  }

  styleCount() {
    const { count } = this.state;
    return count === 0 ? "No Items" : count;
  }
}

export default Item;

我们走吧!当计数为0时,我们看到 "没有项目"。
embedded expressions in react

当数值高于0时,我们会看到这个结果。

  state = {
    count: 500
  };

react embedded function result


在JSX中嵌入表达式 摘要

使用JSX需要一点时间来适应,但随着你对语法的玩弄,很快就会熟悉。此外,使用像Prettier扩展这样的代码格式化器会自动格式化和清理你的JSX,这样就可以用最小的努力来产生漂亮的标记。