在繼續(xù)學(xué)習(xí) React 的第二天里,我們將深入探討 React 中的事件綁定以及如何創(chuàng)建和使用組件。這些基礎(chǔ)知識(shí)將幫助你構(gòu)建動(dòng)態(tài)和交互式的用戶界面。
事件綁定是前端開發(fā)中不可或缺的一部分。在 React 中,事件綁定與傳統(tǒng)的 HTML 有所不同,React 使用了自己的合成事件系統(tǒng)來(lái)處理事件。
在 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;
有時(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;
組件是 React 應(yīng)用的核心單位,它們可以是類組件或函數(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;
類組件提供了更豐富的功能特性,如狀態(tài)(state)和生命周期方法。
import React, { Component } from 'react';
class Welcome extends Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
export default Welcome;
狀態(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;
組件間通信主要通過(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;
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;
通過(guò)第二天的學(xué)習(xí),你應(yīng)該已經(jīng)掌握了 React 中的事件綁定和組件的基本用法。深入理解這些概念將幫助你更好地構(gòu)建復(fù)雜的、可維護(hù)的 React 應(yīng)用。
更多前端開發(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方法
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。