整合營(yíng)銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          React 入門 Day 02:深入理解事件綁定與組

          React 入門 Day 02:深入理解事件綁定與組件

          在繼續(xù)學(xué)習(xí) React 的第二天里,我們將深入探討 React 中的事件綁定以及如何創(chuàng)建和使用組件。這些基礎(chǔ)知識(shí)將幫助你構(gòu)建動(dòng)態(tài)和交互式的用戶界面。


          1. React 中的事件綁定

          事件綁定是前端開發(fā)中不可或缺的一部分。在 React 中,事件綁定與傳統(tǒng)的 HTML 有所不同,React 使用了自己的合成事件系統(tǒng)來(lái)處理事件。

          1.1 基本事件綁定

          在 React 中,可以直接在 JSX 中綁定事件。事件名稱使用 camelCase 命名,并傳入一個(gè)事件處理函數(shù)。

          示例代碼:

          import React from 'react';
          
          class ClickButton extends React.Component {
            handleClick=()=> {
              alert('Button Clicked!');
            };
          
            render() {
              return (
                <button onClick={this.handleClick}>Click Me</button>
              );
            }
          }
          
          export default ClickButton;
          

          1.2 向事件處理函數(shù)傳遞參數(shù)

          有時(shí)需要向事件處理函數(shù)傳遞參數(shù),可以通過(guò)箭頭函數(shù)或 Function.prototype.bind 方法實(shí)現(xiàn)。

          示例代碼:

          import React from 'react';
          
          class ParameterButton extends React.Component {
            handleClick=(param)=> {
              alert(`Button Clicked with parameter: ${param}`);
            };
          
            render() {
              return (
                <button onClick={()=> this.handleClick('Hello')}>Click Me</button>
              );
            }
          }
          
          export default ParameterButton;
          

          2. React 組件

          組件是 React 應(yīng)用的核心單位,它們可以是類組件或函數(shù)組件,并且能夠相互嵌套和組合。

          2.1 函數(shù)組件

          函數(shù)組件是最簡(jiǎn)單的 React 組件。它們僅僅是一個(gè)接受 props 并返回 JSX 的函數(shù)。

          示例代碼:

          import React from 'react';
          
          function Welcome(props) {
            return <h1>Hello, {props.name}</h1>;
          }
          
          export default Welcome;
          

          2.2 類組件

          類組件提供了更豐富的功能特性,如狀態(tài)(state)和生命周期方法。

          示例代碼:

          import React, { Component } from 'react';
          
          class Welcome extends Component {
            render() {
              return <h1>Hello, {this.props.name}</h1>;
            }
          }
          
          export default Welcome;
          

          2.3 組件的狀態(tài) (State)

          狀態(tài)是類組件的一個(gè)核心概念,用于存儲(chǔ)組件的數(shù)據(jù)變化。使用 this.state 初始化狀態(tài),并通過(guò) setState 方法更新狀態(tài)。

          示例代碼:

          import React, { Component } from 'react';
          
          class Counter extends Component {
            constructor(props) {
              super(props);
              this.state={
                count: 0
              };
            }
          
            increment=()=> {
              this.setState({ count: this.state.count + 1 });
            };
          
            render() {
              return (
                <div>
                  <p>Count: {this.state.count}</p>
                  <button onClick={this.increment}>Increment</button>
                </div>
              );
            }
          }
          
          export default Counter;
          

          2.4 組件間通信

          組件間通信主要通過(guò) props 進(jìn)行,父組件可以將數(shù)據(jù)傳遞給子組件,子組件通過(guò) this.props 訪問(wèn)數(shù)據(jù)。

          示例代碼:

          import React from 'react';
          
          function Welcome(props) {
            return <h1>Hello, {props.name}</h1>;
          }
          
          function App() {
            return (
              <div>
                <Welcome name="Alice" />
                <Welcome name="Bob" />
              </div>
            );
          }
          
          export default App;
          

          2.5 組合 vs 繼承

          React 推崇使用組合(composition)而不是繼承(inheritance)來(lái)重用代碼。

          示例代碼:

          import React from 'react';
          
          function FancyBorder(props) {
            return (
              <div className={'FancyBorder FancyBorder-' + props.color}>
                {props.children}
              </div>
            );
          }
          
          function Dialog(props) {
            return (
              <FancyBorder color="blue">
                <h1 className="Dialog-title">
                  {props.title}
                </h1>
                <p className="Dialog-message">
                  {props.message}
                </p>
              </FancyBorder>
            );
          }
          
          function WelcomeDialog() {
            return (
              <Dialog
                title="Welcome"
                message="Thank you for visiting our spacecraft!" />
            );
          }
          
          export default WelcomeDialog;
          

          總結(jié)

          通過(guò)第二天的學(xué)習(xí),你應(yīng)該已經(jīng)掌握了 React 中的事件綁定和組件的基本用法。深入理解這些概念將幫助你更好地構(gòu)建復(fù)雜的、可維護(hù)的 React 應(yīng)用。

          附錄

          1. 推薦閱讀

          • React 官方文檔
          • JavaScript 事件處理

          2. 練習(xí)題

          1. 創(chuàng)建一個(gè)計(jì)數(shù)器組件,實(shí)現(xiàn)加減功能,并將其與父組件進(jìn)行組合。
          2. 創(chuàng)建一個(gè)包含多個(gè)輸入框的表單組件,并實(shí)現(xiàn)表單數(shù)據(jù)的提交和驗(yàn)證。

          更多前端開發(fā)精彩內(nèi)容,請(qǐng)持續(xù)關(guān)注!

          家一定遇到過(guò)在for循環(huán)中創(chuàng)建html元素,并且綁定事件的情況,

          實(shí)際的效果,發(fā)現(xiàn)最后一個(gè)元素的事件將會(huì)覆蓋前面所有元素的事件,如下面的代碼:



          	for (int i=0; i < 10; i++) {
          		var  p=$("<p></p>");
          		p.html(i);
          		var url="http://localhost/p?id="+i;
          		p.click(function(){
          			window.open(url);
          		});
          		$("body").append(p);
          	}


          以上代碼,目測(cè)看沒(méi)有什么問(wèn)題,但是實(shí)際情況是,所有的p元素的click事件都是相同了,最后一次的事件覆蓋了前面所有的事件,

          url都變成了最后一次的,這應(yīng)該是jquery的一個(gè)bug


          那應(yīng)該如何解決呢?


          我稍作調(diào)整,改成以下的就可以了




          	for (int i=0; i < 10; i++) {
          		var  p=$("<p></p>");
          		p.html(i);
          		var url="http://localhost/p?id="+i;
          		p.attr("url",url);
          		p.click(function(){
          			window.open($(this).attr("url"));//此處不能直接寫url
          		});
          		$("body").append(p);
          	}


          這樣,每個(gè)p標(biāo)簽的事件都是獨(dú)立的了。


          網(wǎng)上看了聽說(shuō)可以使用數(shù)組的方法解決,希望有更優(yōu)雅的解決方法,希望大家評(píng)論區(qū)討論貢獻(xiàn)

          先對(duì)原生的addEventListener,removeEventListener兩個(gè)函數(shù),進(jìn)行一定程度的改造。改造邏輯如下:

          //保存Html元素,Html元素被綁定的事件種類,Html元素被綁定事件對(duì)應(yīng)的函數(shù)
          var objectExtraEventListenerMap=new Map();
          //保存原生addEventListener
          EventTarget.prototype.addExtraEventListener=EventTarget.prototype.addEventListener;
          /**
           * 重寫原生addEventListener
           * @param targetType 被綁定的事件
           * @param listener 被綁定到的函數(shù)
           */
          EventTarget.prototype.addEventListener=function(targetType, listener) {
          
          	// 先調(diào)用removeEventListener,刪除已經(jīng)綁定的方法
              this.removeEventListener(targetType, listener.name)
          
              var objectExtraEventMap=objectExtraEventListenerMap.get(this);
              if (typeof objectExtraEventMap=='undefined') {
                  objectExtraEventMap=new Map();
                  objectExtraEventMap.set(targetType, [listener])
              } else {
                  var objectExtraListenerQueue=objectExtraEventMap.get(targetType);
                  if (typeof objectExtraListenerQueue=='undefined') {
                      objectExtraListenerQueue=new Array();
                  }
                  objectExtraListenerQueue.push(listener);
                  objectExtraEventMap.set(targetType, objectExtraListenerQueue)
              }
              objectExtraEventListenerMap.set(this, objectExtraEventMap);
          	// 調(diào)用被保存的原生addEventListener
              this.addExtraEventListener(targetType, listener);
          };
          //保存原生removeEventListener
          EventTarget.prototype.removeExtraEventListener=EventTarget.prototype.removeEventListener;
          /**
           * 重寫原生removeEventListener
           * @param targetType 被綁定的事件
           * @param listener 被綁定到的函數(shù)名
           */
          EventTarget.prototype.removeEventListener=function(targetType, listenerName) {
              var eventTargetObject=this;
              var objectExtraEventMap=objectExtraEventListenerMap.get(eventTargetObject);
              if (typeof objectExtraEventMap !='undefined') {
                  var objectExtraListenerQueue=objectExtraEventMap.get(targetType);
                  if (typeof objectExtraListenerQueue !='undefined') {
                      objectExtraListenerQueue.forEach(function(listenerItem, index, targetQueue) {
                          if (listenerItem.name==listenerName) {
                              targetQueue.splice(index, 1);
          					// 調(diào)用被保存的原生removeEventListener
                              eventTargetObject.removeExtraEventListener(targetType, listenerItem);
                          }
                      });
                  }
              }
          }

          此后,我們可以直接調(diào)用addEventListener方法。不用再手動(dòng)調(diào)用removeEventListener就可以避免重復(fù)綁定事件了。

          HTML代碼

          <input type="text" id="example" name="example">

          JS調(diào)用addEventListener方法


          主站蜘蛛池模板: 国产精品无码亚洲一区二区三区| 超清无码一区二区三区| 亚洲国产成人久久综合一区 | 乱色熟女综合一区二区三区| 亚洲一区二区三区四区视频| 无码毛片一区二区三区视频免费播放 | 在线中文字幕一区| 亚洲国产综合精品中文第一区| 日韩亚洲一区二区三区| 亚州AV综合色区无码一区| 99在线精品一区二区三区| 麻豆文化传媒精品一区二区| 日韩一区二区免费视频| 国产福利一区二区三区在线视频| 四虎精品亚洲一区二区三区| 天天看高清无码一区二区三区| 污污内射在线观看一区二区少妇 | 3D动漫精品啪啪一区二区下载| 国产精品揄拍一区二区久久| 日韩精品中文字幕视频一区| 亚洲乱色熟女一区二区三区丝袜| 亚洲一区影音先锋色资源| 国产激情无码一区二区| 无码一区二区三区AV免费| 国产主播福利一区二区| 国产免费播放一区二区| 一本大道在线无码一区| 国产AV午夜精品一区二区三区| 日本一区二区三区在线观看| 91大神在线精品视频一区| 中文字幕av日韩精品一区二区| 亚洲电影国产一区| 精品免费国产一区二区| 亚洲一区在线视频| 无码人妻精品一区二区三区66| 不卡无码人妻一区三区音频| 精品视频一区二区| 国产不卡视频一区二区三区| 无码AV动漫精品一区二区免费| 尤物精品视频一区二区三区| 中文字幕人妻AV一区二区|