JSX核心语法

什么是JSX?

JSX是JavaScript的一种扩展语法(eXtension),也称为JavaScript XML,因为看起来就像XML语法。JSX是完全包容JS语法的。

const element= <h1></Hello,World!></h2>

上面的代码像什么?像JS,但是js并不能赋值html元素,它就是JSX的语法,并且其完成可以和JavaScript融合在一起使用。

React 认为渲染逻辑本质上与其他 UI 逻辑内在耦合,所以React没有采用标记和逻辑相分离方式,而是将二者共同放在一个组件里面。

JSX中核心语法一

内容:

1.JSX的注释
2.在JSX里面可以正常显示的变量和不可以正常显示的变量
3.JSX嵌入表达式
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div id="root"></div>
  <script src="https://unpkg.com/react@17/umd/react.production.min.js" crossorigin></script>
  <script src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js" crossorigin></script>
  <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>

  <script type="text/babel">
    class App extends React.Component {
      constructor() {
        super();
        this.state =
        {
          user: {
            firstName: 'Harper',
            lastName: 'Perez'
          },

          //1.在{}里可以正常显示的变量 
          name: '权某人', // Sring
          age: 17, // Number
          channel: ["少儿", "卡通", "动漫", "精英"], // Array

          // 2.在{}里不可以正常显示的
          flag: false, // Boolean
          demo1: null,// null
          demo2: undefined, // undefined
          youInfo: {
            name: "某某某",
            age: 18
          }
        }
      }

      formatName(user) {
        console.log(this);
        return user.firstName + ' ' + user.lastName;

      }

      Add(num1, num2) {
        return num1 + num2;
      }

      render() {
        {/*对象结构:*/ }
        const { user, channel } = this.state;
        return (
          <div>
            <h3>Hello {this.formatName(this.state.user)}</h3>
            {/*1.这是JSX的注释*/}
            {/*<h2>哈哈哈</h2>*/}

            {/* 2.JSX嵌入变量 */}
            <h3>{this.state.name}</h3>
            <h3>{this.state.age}</h3>
            <h3>{this.state.channel}</h3>

            {/*这些不能正常显示,如果要强制让它显示的话,,可以通过 1.toString()undefined和NaN,Null没有这个方法;2. 通过String()函数强制类型转换3.+''拼接的方式隐式转换*/}
            <h4>{this.state.flag.toString()}</h4>
            <h4>{this.state.demo1 + ''}</h4>
            <h4>{this.state.demo2}</h4>
            {/*不可以直接把一个对象放在子类里*/}
            {/*<h3>{this.state.youInfo}</h3>*/}

            {/*3.JSX嵌入表达式*/}
            {/*1.运算表达式*/}
            <h6>{10 * 35}</h6>

            {/*2.三目运算符*/}
            <h6>{this.state.flag ? "登录成功" : "请登录啊"}</h6>

            {/*3.函数调用*/}
            <h6>{this.Add(this.state.age, this.state.youInfo.age)}</h6>
            <hr />

            {/*上面大量重复使用了this.state,可以使用对象解构的方式来进行单独拿出*/}
            <h2>{user.firstName}</h2>
            <h2>{channel}</h2>
          </div>
        )
      }
    }
    ReactDOM.render(<App />, document.getElementById("root"));
  </script>
</body>

</html>

JSX核心语法二

内容:

1.JSX绑定属性
  • 比如元素都会用的title
  • img标签的src、a标签的href属性等
  • 元素绑定class
  • 绑定内联style样式
  • 小细节:这里的图片是网易云音乐上面的,假如这个展示图片的元素大小是100px*100px的,而后台传过来的图片是一张很大的图,这样就有点耗费性能和流量,所以可以看到网易云音乐获取图片后面跟了一个参数,可以指定图片的大小的
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>

  <div id="app"></div>
  <script src="https://unpkg.com/react@17/umd/react.production.min.js" crossorigin></script>
  <script src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js" crossorigin></script>
  <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>

  <script type="text/babel">
    class App extends React.Component {
      constructor() {
        super();
        this.state = {
          title: "我是JSX语法的标题",
          imgURL: ["https://p1.music.126.net/Rc-Gc1pjnu39iwB_v98L4w==/109951165758674021.jpg", "http://p1.music.126.net/YFaiQuJm4kxS_xwXFwx5JQ==/109951166630048662.jpg"],
          link: "http://www.baidu.com",
          active: false
        }
      }
      getImgSize(url, size) {
        return url + "?param=" + size + "y" + size;
      }
      render() {
        const { title, imgURL, link, active } = this.state;
        return (
          <div>
            {/* 1.绑定普通属性 */}
            <h3 title="我是标题">h3元素</h3>
            <h3 title={title}>h3元素</h3>
            {/*这里的图片是网易云音乐上面的,假如这个展示图片的元素大小是100px*100px的,而后台传过来的图片是一张很大的图,这样就有点耗费性能和流量,所以可以看到网易云音乐获取图片后面跟了一个参数,可以指定图片的大小的  */}

            {/* <img src={imgURL + "?param=100y100"} alt="" /> */}
            {/* 每次渲染图片都要手动拼接,我们可以封装一个 */}
            <img src={this.getImgSize(imgURL[0], 500)} alt="" />
            <img src={this.getImgSize(imgURL[1], 80)} alt="" />
            <a href={link} target="_blank">百度</a>

            {/* 2.绑定class */}
            {/*class是js里面的关键字*/}
            <div className="price">我是div元素</div>
            <div className={"price title " + (active ? "Active" : "")}>我ye是div元素</div>
            <label htmlFor="">label里面的for也是js是关键字,要用htmlFor</label>
            {/* 3.绑定style样式*/}
            {/*最外层的花括号是jsx语法,里面是一个对象,以键值对的方式,有-的以驼峰命名*/}
            <div style={{ color: "red", fontSize: "55px" }}>我是绑定了style样式</div>
          </div>
        )
      }
    }
    ReactDOM.render(<App />, document.getElementById("app"));

  </script>
</body>
</html>
2.JSX绑定事件
  • 有三种方案:
  • 1.显示绑定bind(this)
  • 2.箭头函数赋值
  • 3.箭头函数里面调用执行的函数
<DOCTYPE html>
  <html lang="en">

  <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
  </head>

  <body>
    <div id="app"></div>
    <script src="https://unpkg.com/react@17/umd/react.production.min.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js" crossorigin></script>
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>

    <script type="text/babel">

      class App extends React.Component {
        constructor() {
          super();
          this.state = {
            message: "Hello",
            counter: 100
          }
          //1.统一绑定事件
          this.btnClick = this.btnClick.bind(this);
        }
        render() {

          return (
            <div>
              {/* 1. 这种点击事件,没有this 需要手动绑定this,如果有很多个点击事件,每个点击事件都要绑定this,我们可以统一绑定this*/}
              <button onClick={this.btnClick.bind(this)}>按钮1啊</button>
              <button onClick={this.btnClick.bind(this)}>按钮1啊</button>

              {/* 2.使用箭头函数 箭头函数给函数*/}
              <button onClick={this.btnTowClick}>按钮2啊</button>

              {/*3.定义箭头函数,箭头函数里面在调用执行的函数*/}
              <button onClick={() => { this.btnThreeClick() }}>按钮3啊</button>
              <div>{this.state.counter}</div>
            </div>
          )
        }
        // 1. 隐式绑定
        btnClick() {
          console.log(this);
        }

        // 2. 箭头函数
        btnTowClick = () => {
          //箭头函数的方式,因为箭头函数里面是没有this的,它会一层一层往上找
          console.log(this);
        }

        // 3. 箭头函数里面调用函数
        btnThreeClick() {
          this.setState({
            counter: this.state.counter - 1
          })
        }

      }
      ReactDOM.render(<App />, document.getElementById("app"));
    </script>
  </body>

  </html>
3.JSX事件/函数传参
<DOCTYPE html>
  <html lang="en">

  <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
  </head>

  <body>
    <div id="app">

    </div>
    <script src="https://unpkg.com/react@17/umd/react.production.min.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js" crossorigin></script>
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>

    <script type="text/babel">
      class App extends React.Component {
        constructor() {
          super();
          this.state = {
            books: ["灵魂的事", "草房子", "周易六十四卦", "你的孤独,虽败犹荣"]

          }
        }
        render() {
          return (
            <div>
              <button onClick={this.btnClick}>点击了</button>
              <ul>
                {
                  this.state.books.map((item, index, obj) => {
                    return <li onClick={() => { this.liClick(item, index, obj, event) }}>{item}</li>
                  })
                }
              </ul>
            </div>
          )
        }
        // 事件里面浏览器封装了一个事件对象,event,里面可以查看它的一些属性(比如点击的位置,坐标等)
        liClick(item, idx, obj, event) {
          console.log(item, idx, obj, event);
        }

        btnClick(e) {
          console.log(e);
        }
      }
      ReactDOM.render(<App />, document.getElementById("app"));
    </script>
</body>
</html>
4.条件渲染
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div id="app"></div>
  <script src="https://unpkg.com/react@17/umd/react.production.min.js" crossorigin></script>
  <script src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js" crossorigin></script>
  <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>

  <script type="text/babel">
    class App extends React.Component {
      constructor() {
        super();
        this.state = {
          isLogin: true
        }
      }
      render() {
        const { isLogin } = this.state;
        let Welcome = null;
        let btnText = null;
        if (this.state.isLogin) {
          Welcome = <h2>欢迎回来</h2>;
          btnText = "退出";
        } else {
          Welcome = <h2>请先登录</h2>;
          btnText = "登录";
        }
        return (
          <div>
            {/* 1.*/}
            {Welcome}
            {/*<button onClick={() => { this.btnClick() }}> {btnText}</button>*/}

            {/*2.三目运算符*/}
            <button onClick={() => { this.btnClick() }}>{isLogin ? "退出" : "请先登录"}</button>

            <hr />
            <h2>{isLogin && "你好,我叫权爷"}</h2>

            {/*3.逻辑&&*/}
            <h2>{isLogin && "你好......"}</h2>
            {isLogin && <h2>你好,包裹我h2不存在</h2>}

          </div >
        )
      }

      //  1.
      btnClick() {
        this.setState({
          isLogin: !this.state.isLogin
        })
      }

    }
    ReactDOM.render(<App />, document.getElementById("app"));
  </script>
</body>
</html>
4.1条件渲染-v-show效果
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <div id="app"></div>
  <script src="https://unpkg.com/react@17/umd/react.production.min.js" crossorigin></script>
  <script src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js" crossorigin></script>
  <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>

  <script type="text/babel">
    class App extends React.Component {
      // 在vue中有v-if和v-show这两个指令可以实现,它们的区别是v-if会使它的dom结构都不存在,而v-show只是改变了display属性。
      constructor() {
        super();
        this.state = {
          isLogin: true

        }
      }
      render() {
        let isDisplay = this.state.isLogin ? "block" : "none";
        let btnText = "点击隐藏"
        return (
          <div>
            <button onClick={() => { this.btnClick() }}>{btnText}</button>
            <h2 style={{ display: isDisplay }}>哈哈哈哈</h2>
          </div>
        )
      }
      btnClick() {
        this.setState({
          isLogin: !this.state.isLogin
        })
      }
    }
    ReactDOM.render(<App />, document.getElementById('app'));
  </script>
</body>
</html>
4.2列表渲染
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div id="app"></div>

  <script src="https://unpkg.com/react@17/umd/react.production.min.js" crossorigin></script>
  <script src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js" crossorigin></script>
  <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
  <script type="text/babel">
    class App extends React.Component {
      constructor() {
        super();
        this.state = {
          arrStr: ['abc', 'cba', 'bcb', 'nba', 'aaa'],
          arrNumber: [20, 50, 1, 234, 34, 55, 9, 100, 33, 53]
        }
      }
      render() {
        return (
          <div>
            <h2>列表1</h2>
            <ul>
              {
                this.state.arrStr.map(item => {
                  return <li>{item}</li>
                })
              }
            </ul>
            {/*如果有一种需求,在一个数组10个元素,只取到大于10的数,或者只取前4个元素*/}
            <h2>数字列表(1.过滤大于10的数)</h2>
            <ul>
              {
                this.state.arrNumber.filter((item) => {
                  return item > 10;
                }).map(val => {
                  return <li>{val}</li>
                })
              }

            </ul>
            <h2>数字列表(2.过滤大于10的数)</h2>
            <ul>
              {/*上面的1.过滤可以改:*/}
              {
                this.state.arrNumber.filter(item => item > 10).map(item => <li>{item}</li>)
              }
            </ul>

            <h2>数字列表(截取)</h2>
            <ul>
              {
                this.state.arrNumber.splice(0, 4).map(item => {
                  return <li>{item}</li>
                })
              }
            </ul>
          </div>
        )
      }
    }
    ReactDOM.render(<App />, document.getElementById("app"));
  </script>
</body>
</html>