jsx理解

jsx学习

JSX 其实会被转化为普通的 JavaScript 对象。


function getGreeting(user) {
  if (user) {
    return <h1>Hello, {formatName(user)}!</h1>;
  }
  return <h1>Hello, Stranger.</h1>;
}

其中jsx中可以含有双标签也可以含有单标签

jsx顶层只能有一个根元素,很多时候我们会在外层包裹一个div

render(){
    return (
        <div>
            <h2>计数器 :{this.state.counter}</h2>
            <button onClick={this.increase.bind(this)}> +1 </button>
            <button onClick={this.decrease.bind(this)}> -1 </button>
        </div>
        <img src="" /> //单标签中最后的结尾必须是/
    )
}

在jsx中如何写注释呢?

render(){
    return(
        <div>
            {/*这是一段注释*/}
            <h2>我是测试</h2>
        </div>
    )
}
jsx中如何嵌入数据
  • String类型,Number类型和Array类型可以直接正常显示
  • 当变量是null、undefined、Boolean类型时,不显示,如果希望显示,则需将其转成字符串,通过toString(),拼接字符串,或者直接Sting(变量)
  • 对象不能作为jsx的子类
<script type="text/babel">
class App extends React.Component{
    constructor(){
        super();
        
        this.state={
            name : "qiqi",
            age : 20,
            like : ["banner","orange","apple"],
            
            test1 : null,
            test2 : undefined,
            test3 : true,

            parent :{
                name  : "lizi",
                age : 40
            }
        }
    }

    render(){
        return (
            <div>
                <h2>{this.state.name}</h2>;
                <h2>{this.state.age}</h2>;
                <h2>{this.state.like}</h2>;
                
                <h2>{this.state.test1 + ""}</h2>;
                <h2>{this.state.test2 + ""}</h2>;
                <h2>{this.state.test3.toString()}</h2>;
            </div>
        )
    }
}

    ReactDOM.render(<App/>,document.getElementById("app"));
</script>
jsx中如何嵌入表达式
  1. 运算符表达式
  2. 三目运算符
  3. 函数表达式
<script type="text/babel">
class App extends React.Component{
    constructor(props){
        super(props);
        
        this.state={
            Firstname : "qiqi",
            Lastname : "zi"
        }
    }

    render(){
        const {Firstname , Lastname} = this.state;//数据的解构
        return (
            <div> 
                {/*运算符表达式*/}
                <h2>{Firstname + Lastname}</h2>
                <h2>{10 * 15}</h2>
                {/*三目运算符*/}
                <h2>{true ? '111' : '000'}</h2>
                {/*函数调用*/}
                <h2>{this.fun()}</h2>
            </div>
        )
    }

    fun(){
        return this.state.Firstname + "" + this.state.Lastname;
    }
}

    ReactDOM.render(<App/>,document.getElementById("app"));
</script>
jsx的使用

很多时候,描述的HTML原生会有一些属性,而我们希望这些属性也是动态的:

  • 比如元素都会有title属性

  • 比如img元素会有src属性

  • 比如a元素会有href属性

  • 比如元素可能需要绑定class

    • 注意:绑定class比较特殊,因为class在js中是一个关键字,所以jsx中不允许直接写class
    • 写法:使用className替代
  • 比如原生使用内联样式style

    • style后面跟的是一个对象类型,对象中是样式的属性名和属性值;
    • 注意:这里会讲属性名转成驼峰标识,而不是连接符-;
      我们来演示一下属性的绑定:
<script type="text/babel">
    function getSize(imgUrl , size){
        return imgUrl + `?param=${size}x${size}`
    }
    class App extends React.Component {
        constructor(props) {
            super(props);

            this.state = {
                title: "你好啊",
                imgUrl:
                    "https://upload.jianshu.io/users/upload_avatars/1102036/c3628b478f06.jpeg?imageMogr2/auto-orient/strip|imageView2/1/w/240/h/240",
                link: "https://www.baidu.com",
                active: false
            }
        }

        render() {
            return (
                <div>
                    {/*绑定普通属性*/}
                    <h2 title={this.state.title}>Hello World</h2>
                    <img src={this.state.imgUrl} alt="" />
                    <a href={this.state.link} target="_blank">百度一下</a>
                    {/*绑定class属性*/}
                    <div className={"message " + (this.state.active ? " active" : "")}>你好啊</div>
                    <div className={["message", (this.state.active ? "active" : "")].join(" ")}>你好啊</div>
                    {/*绑定style*/}
                    <div style={{ fontSize: "30px", color: "red", backgroundColor: "blue" }}>我是文本</div>
                </div>
            )
        }
    }
    ReactDOM.render(<App />, document.getElementById("app"));
</script>

jsx事件监听

和原生绑定区别

如果原生DOM原生有一个监听事件,我们可以如何操作呢?

  • 方式一:获取DOM原生,添加监听事件;
  • 方式二:在HTML原生中,直接绑定onclick;

我们这里演练一下方式二:

  • btnClick()这样写的原因是onclick绑定的后面是跟上JavaScript代码;
<button onclick="btnClick()">点我一下</button>
<script>
  function btnClick() {
  console.log("按钮发生了点击");
}
</script>

在React中是如何操作呢?

我们来实现一下React中的事件监听,这里主要有两点不同

  • React 事件的命名采用小驼峰式(camelCase),而不是纯小写;
  • 我们需要通过{}传入一个事件处理函数,这个函数会在事件发生时被执行;
class App extends React.Component {
  render() {
    return (
      <div>
        <button onClick={this.btnClick}>点我一下(React)</button>
      </div>
    )
  }

  btnClick() {
    console.log("React按钮点击了一下")
  }
}
this绑定问题

在事件执行后,我们可能需要获取当前类的对象中相关的属性:

  • 比如我们这里打印:this.state.message
    • 但是这里会报错:Cannot read property ‘state’ of undefined
    • 原因是this在这里是undefined
  • 如果我们这里直接打印this,也会发现它是一个undefined
class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      message: "你好啊,李银河"
    }
  }

  render() {
    return (
      <div>
        <button onClick={this.btnClick}>点我一下(React)</button>
      </div>
    )
  }

  btnClick() {
    console.log(this);
    console.log(this.state.message);
  }
}

为什么是undefined呢?

  • 原因是btnClick函数并不是我们主动调用的,而且当button发生改变时,React内部调用了btnClick函数;
  • 而它内部调用时,并不知道要如何绑定正确的this;
如何解决this的问题呢?
方案一:bind给btnClick显示绑定this

在传入函数时,我们可以主动绑定this:

  • 这里我们主动将btnClick中的this通过bind来进行绑定(显示绑定)
  • 那么之后React内部调用btnClick函数时,就会有一个this,并且是我们绑定的this;
<button onClick={this.btnClick.bind(this)}>点我一下(React)</button>

但是呢,如果我有两个函数都需要用到btnClick的绑定:
我们发现 bind(this) 需要书写两遍;

<button onClick={this.btnClick.bind(this)}>点我一下(React)</button>
<button onClick={this.btnClick.bind(this)}>也点我一下(React)</button>

这个我们可以通过在构造方法中直接给this.btnClick绑定this来解决:

  • 注意查看 constructor 中我们的操作:this.btnClick = this.btnClick.bind(this);
class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      message: "你好啊,李银河"
    }

    this.btnClick = this.btnClick.bind(this);
  }

  render() {
    return (
      <div>
        <button onClick={this.btnClick}>点我一下(React)</button>
        <button onClick={this.btnClick}>也点我一下(React)</button>
      </div>
    )
  }

  btnClick() {
    console.log(this);
    console.log(this.state.message);
  }
}
方案二:使用 ES6 class fields 语法

你会发现我这里将btnClick的定义变成了一种赋值语句:

  • 这是ES6中给类定义属性的方法,称之为class fields语法;
  • 因为这里我们赋值时,使用了箭头函数,所以在当前函数中的this会去上一个作用域中查找;
  • 而上一个作用域中的this就是当前的对象;
class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      message: "你好啊,李银河"
    }
  }

  render() {
    return (
      <div>
        <button onClick={this.btnClick}>点我一下(React)</button>
        <button onClick={this.btnClick}>也点我一下(React)</button>
      </div>
    )
  }

  btnClick = () => {
    console.log(this);
    console.log(this.state.message);
  }
}
方案三:事件监听时传入箭头函数(推荐)

因为 onClick 中要求我们传入一个函数,那么我们可以直接定义一个箭头函数传入:

  • 传入的箭头函数的函数体是我们需要执行的代码,我们直接执行 this.btnClick();
  • this.btnClick()中通过this来指定会进行隐式绑定,最终this也是正确的;
class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      message: "你好啊,李银河"
    }
  }

  render() {
    return (
      <div>
        <button onClick={() => this.btnClick()}>点我一下(React)</button>
        <button onClick={() => this.btnClick()}>也点我一下(React)</button>
      </div>
    )
  }

  btnClick() {
    console.log(this);
    console.log(this.state.message);
  }
}
事件参数传递

在执行事件函数时,有可能我们需要获取一些参数信息:比如event对象、其他参数

情况一:获取event对象

  • 很多时候我们需要拿到event对象来做一些事情(比如阻止默认行为)
  • 假如我们用不到this,那么直接传入函数就可以获取到event对象;
class App extends React.Component {
  constructor(props) {

  render() {
    return (
      <div>
        <a href="http://www.baidu.com" onClick={this.btnClick}>点我一下</a>
      </div>
    )
  }

  btnClick(e) {
    e.preventDefault();
    console.log(e);
  }
}

情况二:获取更多参数

  • 有更多参数时,我们最好的方式就是传入一个箭头函数,主动- - 执行的事件函数,并且传入相关的其他参数;
class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      names: ["衣服", "鞋子", "裤子"]
    }
  }

  render() {
    return (
      <div>
        <a href="http://www.baidu.com" onClick={this.aClick}>点我一下</a>

        {
          this.state.names.map((item, index) => {
            return (
              <a href="#" onClick={e => this.aClick(e, item, index)}>{item}</a>
            )
          })
        }
      </div>
    )
  }

  aClick(e, item, index) {
    e.preventDefault();
    console.log(item, index);
    console.log(e);
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值