Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
在繼續學習 React 的第二天里,我們將深入探討 React 中的事件綁定以及如何創建和使用組件。這些基礎知識將幫助你構建動態和交互式的用戶界面。
事件綁定是前端開發中不可或缺的一部分。在 React 中,事件綁定與傳統的 HTML 有所不同,React 使用了自己的合成事件系統來處理事件。
在 React 中,可以直接在 JSX 中綁定事件。事件名稱使用 camelCase 命名,并傳入一個事件處理函數。
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;
有時需要向事件處理函數傳遞參數,可以通過箭頭函數或 Function.prototype.bind 方法實現。
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 應用的核心單位,它們可以是類組件或函數組件,并且能夠相互嵌套和組合。
函數組件是最簡單的 React 組件。它們僅僅是一個接受 props 并返回 JSX 的函數。
import React from 'react';
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
export default Welcome;
類組件提供了更豐富的功能特性,如狀態(state)和生命周期方法。
import React, { Component } from 'react';
class Welcome extends Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
export default Welcome;
狀態是類組件的一個核心概念,用于存儲組件的數據變化。使用 this.state 初始化狀態,并通過 setState 方法更新狀態。
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;
組件間通信主要通過 props 進行,父組件可以將數據傳遞給子組件,子組件通過 this.props 訪問數據。
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)來重用代碼。
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;
通過第二天的學習,你應該已經掌握了 React 中的事件綁定和組件的基本用法。深入理解這些概念將幫助你更好地構建復雜的、可維護的 React 應用。
更多前端開發精彩內容,請持續關注!
家一定遇到過在for循環中創建html元素,并且綁定事件的情況,
實際的效果,發現最后一個元素的事件將會覆蓋前面所有元素的事件,如下面的代碼:
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);
}
以上代碼,目測看沒有什么問題,但是實際情況是,所有的p元素的click事件都是相同了,最后一次的事件覆蓋了前面所有的事件,
url都變成了最后一次的,這應該是jquery的一個bug
那應該如何解決呢?
我稍作調整,改成以下的就可以了
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);
}
這樣,每個p標簽的事件都是獨立的了。
網上看了聽說可以使用數組的方法解決,希望有更優雅的解決方法,希望大家評論區討論貢獻
先對原生的addEventListener,removeEventListener兩個函數,進行一定程度的改造。改造邏輯如下:
//保存Html元素,Html元素被綁定的事件種類,Html元素被綁定事件對應的函數
var objectExtraEventListenerMap=new Map();
//保存原生addEventListener
EventTarget.prototype.addExtraEventListener=EventTarget.prototype.addEventListener;
/**
* 重寫原生addEventListener
* @param targetType 被綁定的事件
* @param listener 被綁定到的函數
*/
EventTarget.prototype.addEventListener=function(targetType, listener) {
// 先調用removeEventListener,刪除已經綁定的方法
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);
// 調用被保存的原生addEventListener
this.addExtraEventListener(targetType, listener);
};
//保存原生removeEventListener
EventTarget.prototype.removeExtraEventListener=EventTarget.prototype.removeEventListener;
/**
* 重寫原生removeEventListener
* @param targetType 被綁定的事件
* @param listener 被綁定到的函數名
*/
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);
// 調用被保存的原生removeEventListener
eventTargetObject.removeExtraEventListener(targetType, listenerItem);
}
});
}
}
}
此后,我們可以直接調用addEventListener方法。不用再手動調用removeEventListener就可以避免重復綁定事件了。
HTML代碼
<input type="text" id="example" name="example">
JS調用addEventListener方法
*請認真填寫需求信息,我們會在24小時內與您取得聯系。