学习react第二天_JSX的语法this指向_列表渲染

文章详细介绍了JSX中的事件绑定,包括this的四种绑定规则,以及如何解决在事件处理函数中this为undefined的问题,提出了bind、ES6classfields和箭头函数的解决方案。同时,文章还讨论了参数传递、条件渲染(if和三元运算符)以及列表渲染(使用map函数)在React中的应用。此外,提到了key在列表渲染中的重要性以及对优化的影响。
摘要由CSDN通过智能技术生成

一. JSX的语法

1.1. 事件绑定

1.1.1. this绑定

在事件执行后,我们可能需要获取当前类的对象中相关的属性,这个时候需要用到this

如果我们这里直接打印this,也会发现它是一个undefined 

◼ 为什么是undefined呢?

 原因是btnClick函数并不是我们主动调用的,而且当button发生改变时,React内部调用了btnClick函数;

 而它内部调用时,并不知道要如何绑定正确的this;

◼ 如何解决this的问题呢?

 方案一:bind给btnClick显示绑定this

 方案二:使用 ES6 class fields 语法

 方案三:事件监听时传入箭头函数(个人推荐)

const obj = {
      foo: function() {
        console.log('foo:' , this);
      }
    }
    obj.foo() 

    const config = {
      onClick: obj.foo.bind(obj) // onClick 的 this 指向的是 foo, 使用 bind 指向 obj
    }

    const click = config.onClick // onClick赋值给了 click,所以 click 指向的也是 foo
    click() // 做了click的调用,这里的this的默认调用指向 window ,但是在 babel 模式下,this 指向 undefined

this 的四种绑定规则:

      1. 默认绑定: 独立执行 foo()

      2. 隐式绑定: 被一个对象执行 obj.foo() -> 此时 this 指向 obj

      3. 显式绑定: call/apply/bind foo.call("aaa") ->String("aaa")

      4. new 绑定: new foo() -> 创建一个对象,并且赋值给 this

btn1Click() {
      // console.log(this); // 这里的 this 指向的是 undefined
      this.setState({counter: this.state.counter + 1})
    }

    btn2Click = () => {
      console.log("btn2Click:", this);
      this.setState({counter: 1000})
    }

    btn3Click() {
      console.log('btn3Click:', this);
      this.setState({counter: 500})
    }
    // this.btn1Click 这里的this没有执行,所以不是隐式绑定
      render() {
        const {message, counter} = this.state
        return (
          <div>
            {/*1. this的绑定方式一:bind 绑定*/}
            <button onClick={this.btn1Click}>按钮1</button>

            {/*2. this的绑定方式二:ES6 class filed*/}
            <button onClick={this.btn2Click}>按钮2</button>

            {/*3. this的绑定方法三:直接传入一个箭头函数(重要),当箭头函数被执行,就执行btn3Click,此时进行了一个隐式绑定,this指向的是 App*/}
            <button onClick={()=>console.log("btn3Click")}>按钮3</button>
            <button onClick={()=>this.btn3Click()}>按钮3</button>
            <h1>当前计数: {counter}</h1>
          </div>
        )
      }

1.1.2. 传递参数

  • event

    • btnClick(event) {
              console.log("btnClick", event, this );
              
            }
       {/* 1.event 参数的传递*/}
                  <button onClick={this.btnClick.bind(this)}>按钮1</button>
                  <button onClick={(event)=> this.btnClick(event)}>按钮2</button>

  • 额外的参数

    •  btnClick(event, name, age) {
              console.log("btnClick", event, this );
              console.log("name, age", name, age);
            }
       {/* 2.额外的参数传递*/}
                  {/*不推荐在bind后面添加参数,因为还会向参数的最后一个形参中传递 event,参数不对应
                    推荐箭头函数传参,传递参数的时候数据更加清晰
                  */}
                  <button onClick={this.btnClick.bind(this, 'cobe', 30)}>按钮3(不推荐)</button>
                  <button onClick={(event)=> this.btnClick(event, 'cobe', 18)}>按钮3</button>

1.1.3 案例-电影列表选中

<script type="text/babel">

    // 创建组件
    class App extends React.Component {
      constructor() {
        super()
        this.state = {
          movies: ['大话西游', '星级穿越', '冰雪奇缘', '万里归途'],
          currentIndex: 0
        }
      }
      
      itemClick(index) {
        // console.log('itemClick');
        this.setState({currentIndex:index})
      }
    
      render() {
        const {message, movies, currentIndex} = this.state
        return (
          <div>
            <ul>
              {movies.map((item, index) => {
                return ( 
                  <li 
                  class={currentIndex === index? 'active' : '' }
                  onClick={() => this.itemClick(index)}
                  >
                  {item}
                  </li> 
                )
              })
            }
            </ul>
          </div>
        )
      }

    }

    // 创建 root 根,渲染组件
    const root = ReactDOM.createRoot(document.querySelector('#root'))
    root.render(<App/>)
  </script>

babel官网:https://babeljs.io/repl/#?presets=react

1.2. jsx条件渲染

  • if判断

    • 适合逻辑较多的情况

    • // 1.条件判断方式一:使用 if 进行条件判断
              if(isReady) {
                showElement = <h1>开始比赛吧!</h1>
              } else {
                showElement = <h2>请提前做好准备!</h2>
              }
              return (
                <div>
                  {/* 1.方式一:根据条件给变量赋值不同的内容*/}
                  {showElement}
                </div>

  • 三元运算符

    • 适合逻辑比较简单

    • <div>{ isReady ? <button>开始战斗!</button> : <h3>请立即做好准备</h3> }</div>

  • &&逻辑与

    • 适合如果条件成立,渲染某一个组件;如果条件不成立,什么内容也不渲染;
    • friend: {
                  name: 'kobe',
                  saying: '凌晨四点钟的太阳'
                }
      
      
      {/* 3.方式三:逻辑与运算符*/}
                  {/* 场景:当某一个值可能是 undefined 时,使用 &&进行条件判断*/}
                  <div>{friend && <div>{friend.name + ' ' + friend.saying}</div> }</div>

  • v-show实现效果:主要是控制display属性是否为none

    •  {/* 用 v-show */}
                  <h2 style={{display: show? 'block':'none'}}>使用v-show通过display控制显示隐藏</h2>

1.3. jsx列表渲染

  • map高阶函数(重要)

  • filter:过滤掉一些内容

  • slice:截取数组中的一部分

  • key主要的作用是为了提高diff算法时的效率;

// 创建组件
    class App extends React.Component {
      constructor() {
        super()
        this.state = {
          message: "Hello",
          students: [
            {id: 1111, name: 'daming', score: 99},
            {id: 1112, name: 'liming', score: 78},
            {id: 1113, name: 'lingling', score: 110},
            {id: 1114, name: 'funny', score: 100},
            {id: 1115, name: 'lili', score: 140},
            {id: 1116, name: 'bobo', score: 120},
          ]
        }
      }
      
    
      render() {
        const {message, students} = this.state

        // 分数大于 100 的显示
        const filterStudents = students.filter(item => {
          return item.score > 100
        })

        // 分数大于100,且只展示两人的显示
        // slice(start, end): [start, end).包含起始不包含最后的数
        const sliceStudents = students.slice(0,2)
        return (
          <div>
            <h2>学生列表数据</h2>
            <div className="list">
              {
                students.filter(item => item.score>100).slice(0,2).map((item) => {
                return (
                  <div className="item" key={item.id}>
                    <h1>学号: {item.id}</h1>
                    <h2>姓名: {item.name}</h2>
                    <h2>分数: {item.score}</h2>
                  </div>
                  )
                })
              }
              </div>
          </div>
        )
      }

    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值