React JSX基础之最终篇(也是下一个开始)

109 阅读6分钟

JSX元素事件

目标:掌握jsx中为元素添加事件的方式


1.绑定事件

jsx中,时间名称采用驼峰式命名法,事件处理函数通过插值表达式嵌入到JSX中。

语法:on+时间名称 = {事件处理程序},比如 onClick={onClickHandler}

function onClickHandler() {
  console.log("clicked")
}
// 此处需要特别注意:在为事件添加事件处理函数时,传入的一定是事件处理函数本身,而不是加括号形式的函数调用
const jsx = <button onClick={onClickHandler}>button</button>
// 以下为错误写法
// 以下代码的含义是,调用 sayHello 方法,将sayHello方法的返回值赋值给onClick属性
const jsx = <button onlick={onClickHandler()}>点击我是错误写法</button>
// 很多时候,事件处理函数中只有少量代码,我们也会将事件处理函数写在行内,写成匿名的箭头函数
const jsx = <button onClick={()=>console.log("clicked")}>hello</button>

2.事件函数传惨

在事件处理函数需要传递参数的情况下,我们可以先添加行内匿名箭头函数,当事件被触发后,先执行内匿名箭头函数,再再行内匿名箭头函数中调用真正的事件处理函数,此时真正的事件处理函数就可以添加用于调用函数的小括号了,在小括号里就可以实现参数的传递了。

function onClickHandler(arg1,arg2) {
  console.log(arg1);
  console.log(arg2);
}
​
const jsx = <button onClick={()=> onClickHandler("a","b")}>button</button>

3.事件对象

  • 在默认情况下,事件处理函数的第一个参数是事件对象。
function onClickHandler(event) {
  console.log(event)
}
​
const jsx = <button onClick={onClickHandler}></button>
  • 在事件处理函数需要传递参数的情况下,开发者需要显示将事件对象传递到真实的事件处理函数中。
function onClickHandler(arg1,arg2,event) {
  console.log(arg1);
  console.log(arg2);
  console.log(event);
}
​
const jsx = <button onClick={(event)=>onClickHandler("a","b",event)}>button</button>

4.this关键字

  • jsx中,事件处理函数中的this并不指向触发事件的元素,而是指向undefined。
  • 因为在React不推荐我们直接操作DOM对象,而是要通过数据的改变驱动DOM的更新


JSX综合案例—选项卡

  • 第一步
body,
h4,
ul {
  margin: 0;
}
​
ul {
  padding: 0;
  list-style: none;
}
​
.container {
  width: 500px;
  margin: 70px auto 0;
}
​
.tab-title {
  display: flex;
  border-bottom: 1px solid #c9dff4;
  height: 40px;
  margin-bottom: 22px;
}
​
.tab-title h4 {
  font-size: 20px;
  color: #404040;
  font-weight: normal;
  margin-right: 35px;
  cursor: pointer;
}
​
.tab-title .active {
  color: #1479d7;
  border-bottom: 4px solid #0276da;
}
​
.tab-content li {
  font-size: 16px;
  line-height: 36px;
  white-space: nowrap;
  text-overflow: ellipsis;
  overflow: hidden;
}
​
.tab-content .headline {
  display: flex;
  align-items: flex-start;
  margin-bottom: 12px;
}
​
.tab-content .headline img {
  width: 214px;
  height: 120px;
}
​
.tab-content .headline .content {
  margin-left: 16px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  height: 120px;
}
​
.tab-content  ul {
  display: none;
}
​
.tab-content .active {
  display: block;
}
​
.tab-content .headline h3 {
  margin: 0;
  font-size: 16px;
  color: #333;
  white-space: normal;
  font-weight: normal;
  line-height: normal;
}
​
.tab-content .headline span {
  font-size: 13px;
  color: #64788c;
  line-height: normal;
}
  • 第二步
const jsx = (
  <div className="container">
    <div className="tab-title">
      <h4 className="active">娱乐</h4>
      <h4>电视剧</h4>
      <h4>电影</h4>
      <h4>音乐</h4>
    </div>
    <div className="tab-content">
      <ul className="active">
        <li className="headline">
          <img
            src="https://inews.gtimg.com/newsapp_ls/0/15171720914_640330/0"
            alt=""
          />
          <div className="content">
            <h3>马思纯开豪车逆向行驶,违反交规被通报罚款扣分记3分</h3>
            <span>我娱有约 12评</span>
          </div>
        </li>
        <li>从港剧歌手到《金宵大厦》演斯文败类,转型路上他最感恩马国明</li>
        <li>《新神榜:杨戬》定档8月19日,神话宇宙能否再度封神?</li>
        <li>北京交警通报网传“马某某交通违法”情况:驾车逆行被罚款计分</li>
        <li>曲折上升,吴磊的转型进行时</li>
        <li>这部草根纪录片,能治好我们的精神内耗吗</li>
        <li>胡一天说《民国大侦探》司徒颜不是徒有颜值,认证路垚更吃货</li>
      </ul>
    </div>
  </div>
);
  • 第三步进行修改
import React from "react";
import ReactDOM from "react-dom/client";
//导入全局样式
import "./styles.css";
​
//模拟数据
const response = [  {    type: "娱乐",    list: [      {        title: "马思纯开豪车逆向行驶,违反交规被通报罚款扣分记3分",        imageUrl: "https://inews.gtimg.com/newsapp_ls/0/15171720914_640330/0",        comment: 10,        from: "我娱有约",      },      { title: "从港剧歌手到《金宵大厦》演斯文败类,转型路上他最感恩马国明" },      { title: "《新神榜:杨戬》定档8月19日,神话宇宙能否再度封神?" },      { title: "北京交警通报网传“马某某交通违法”情况:驾车逆行被罚款计分" },      { title: "曲折上升,吴磊的转型进行时" },      { title: "这部草根纪录片,能治好我们的精神内耗吗" },      { title: "胡一天说《民国大侦探》司徒颜不是徒有颜值,认证路垚更吃货" },    ],
  },
  {
    type: "电视剧",
    list: [
      {
        title: "《玫瑰之战》袁泉颜值抗打,黄晓明不再油腻,为何输了口碑?",
        imageUrl: "https://inews.gtimg.com/newsapp_ls/0/15168602214_294195/0",
        comment: 5,
        from: "文拉法辛",
      },
      { title: "同剧中,当女配冒充女主,两人同款造型,就很考验女主颜值了" },
      { title: "仙侠剧:越拍越精美,越拍越架空,越拍越世俗" },
      { title: "4部古装剧,《琅琊榜》《甄嬛传》拿不到第1,第4部15年无法超越" },
      { title: "热度第一,全网刷屏,这剧烂不烂?" },
      { title: "《欢乐颂3》:为啥影视剧中穷人住的都是豪宅?" },
      { title: "《人世间》后又一大剧,芒果抽到“爆款”了,还诞生了“邪门CP”" },
    ],
  },
  {
    type: "电影",
    list: [
      {
        title: "王一博微博之夜红毯造型合集,荣获年度最受期待影片奖项",
        imageUrl: "https://inews.gtimg.com/newsapp_ls/0/15168588151_294195/0",
        comment: 20,
        from: "胖编怪聊",
      },
      { title: "10天仅收3.4亿!《明日战记》票房拉垮,古天乐拉票房让人心疼" },
      { title: "刘亦菲亮片点缀长裙优雅温柔 亮相微博电影之夜" },
      { title: "华谊王中磊:不会躺平,计划未来两年推出两部虚拟拍摄为主的电影" },
      { title: "秒售罄!尔冬升新作《海的尽头是草原》到底怎么样?" },
      { title: "1988年,好莱坞唯一一部在俄罗斯红场拍摄的电影《红场特警》上映" },
      { title: "微博电影之夜谁最火?王一博沈腾横扫热搜" },
    ],
  },
  {
    type: "音乐",
    list: [
      {
        title: "徐沛东:曾创作雍正王朝主题曲,一句失误惨遭下课,今近况如何",
        imageUrl: "https://inews.gtimg.com/newsapp_ls/0/15168556970_294195/0",
        comment: 50,
        from: "无影剪哥",
      },
      { title: "微博电影之夜:周深串烧歌曲展现真实唱功,单依纯稳定发挥获称赞" },
      { title: "好声音音源数据:李楚楚飙升榜排名第二,浙音学子潘韵淇未进前十" },
      { title: "中国首次曝光“垃圾”水乳!大牌上榜!国货真牛!" },
      { title: "黄霄雲使用按键留人,梁静茹率先出现组内PK,廖昌永收获学员" },
      { title: "“那个夏天”长沙交响乐团Melete室内乐团专场音乐会精彩上演" },
      { title: "陈奕迅主唱《孤勇者》背后的励志故事" },
    ],
  },
];
​
const jsx = (
  <div className="container">
    <div className="tab-title">
      {response.map((item, index) => (
        <h4 key={index}>{item.type}</h4>
      ))}
    </div>
    <div className="tab-content">
      {response.map((item, index) => {
        return (
          <ul className="active" key={index}>
            {item.list.map((subitem, index) => {
              if (index === 0) {
                return (
                  <li>
                    <img src={subitem.imageUrl} alt="" />
                    <div className="content">
                      <h3>{subitem.title}</h3>
                      <span>
                        {subitem.from} {subitem.comment}评
                      </span>
                    </div>
                  </li>
                );
              } else {
                return <li key={index}>{subitem.title}</li>;
              }
            })}
          </ul>
        );
      })}
    </div>
  </div>
);
​
const root = ReactDOM.createRoot(document.getElementById("root"));
​
root.render(jsx);
​

小总结

  • 在 JSX 中如何为元素绑定事件

    • 事件名称采用小驼峰式命名法,比如onClick
    • 事件名称的值为事件处理函数,通过插值的方式赋值,比如
  • 如何获取事件对象

    • 函数的第一个参数即为事件对象

      <div onClick={onClickHandler}></div>
      
    • 通过传递参数的方式将事件对象传递给真正的事件处理函数

      <div onClick={(event)=>onClickHandler(event)}></div>
      
  • 描述一下事件处理函数中的 this 指向

    //1.<div onClick={onClickHandler}></div> => undefined
    ​
    //2.<div onClick={(event)=>onClickHandler(event)}></div> =>dang
    
  • 如何为事件处理函数传递参数

     <div onClick={(e) => onClickHandler(e, arg)}></div>
    
    • 在元素行内先写一个匿名箭头函数, 在箭头函数中调用真正的事件处理函数, 此时即可为真正的事件处理函数传递参数了.