React組件(二):常見屬性和函數

文章目錄

    • 一、defaultProps 和 prop-types
      • 使用 defaultProps 設置組件的默認值
      • 使用prop-types進行props數據類型的校驗
      • 代碼舉例
    • 二、事件綁定
      • 原生js做事件綁定
      • 使用 React 提供的方法,做事件綁定
    • 三、生命周期函數:shouldComponentUpdate()
    • 四、在js代碼中獲取html標簽的屬性
    • 五、生命周期函數:componentWillReceiveProps()

一、defaultProps 和 prop-types

使用 defaultProps 設置組件的默認值

React 中,使用靜態的 defaultProps 屬性,來設置組件的默認屬性值。

格式舉例:

  // 在 React 中,使用靜態的 defaultProps 屬性,來設置組件的默認屬性值static defaultProps = {initcount: 0 // 如果外界沒有傳遞 initcount,那么,自己初始化一個數值(比如0)};

使用prop-types進行props數據類型的校驗

在組件中,可以通過 prop-types 把外界傳遞過來的屬性,做類型校驗。如果類型不匹配,控制臺會彈出告警。

注意:如果要為 傳遞過來的屬性做類型校驗,必須安裝 React 提供的 第三方包,叫做 prop-types

格式舉例:

  static propTypes = {initcount: ReactTypes.number // 使用 prop-types 包,來定義 initcount 為 number 類型};

下方代碼中,在引用組件的時候,如果類型不匹配:

// 使用 render 函數渲染 虛擬DOM
ReactDOM.render(<div>{/* 規定,每個用戶在使用 組件的時候,必須傳遞一個 默認的 數值,作為 組件初始化的 數據 */}<Counter initcount="我是string類型"></Counter></div>,document.getElementById("app")
);

代碼舉例

我們把 defaultPropsprop-types 來舉個例子。

(1)index.html:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head><body><!-- 容器,通過 React 渲染得到的 虛擬DOM,會呈現到這個位置 --><div id="app"></div>
</body></html>

(2)main.js:

// JS打包入口文件
// 1. 導入包
import React from "react";
import ReactDOM from "react-dom";// 導入計數器組件
import Counter from "./components/Counter.jsx";// 使用 render 函數渲染 虛擬DOM
ReactDOM.render(<div>{/* 規定,每個用戶在使用 組件的時候,必須傳遞一個 默認的 數值,作為 組件初始化的 數據 */}<Counter initcount={0}></Counter></div>,document.getElementById("app")
);

(3)/components/Counter.jsx:

import React from "react";
// 注意: prop-types 包中職能跟單一,只提供了 一些常見的 數據類型,用于做類型校驗
import ReactTypes from "prop-types";export default class Counter extends React.Component {constructor(props) {super(props);// 初始化組件,保存的是組件的私有數據this.state = {msg: "ok",count: props.initcount // 把 父組件傳遞過來的 initcount 賦值給子組件 state 中的 count值。這樣的話,就把 count 值改成了可讀可寫的 state 屬性。因此,以后就能實現“點擊 按鈕 ,count 值 + 1”的需求了};}// 在 React 中,使用靜態的 defaultProps 屬性,來設置組件的默認屬性值static defaultProps = {initcount: 0 // 如果外界沒有傳遞 initcount,那么,自己初始化一個 數值,為0};render() {return (<div><div><h3>這是 Counter 計數器組件 </h3><p>當前的計數是:{this.state.count}</p></div></div>);// 當 return 執行完畢后, 虛擬DOM創建好了,但是,還沒有掛載到真正的頁面中}
}

二、事件綁定

案例:點擊按鈕后,計數器 +1。

原生js做事件綁定

代碼舉例:

(1)index.html:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head><body><!-- 容器,通過 React 渲染得到的 虛擬DOM,會呈現到這個位置 --><div id="app"></div>
</body></html>

(2)main.js:

// JS打包入口文件
// 1. 導入包
import React from "react";
import ReactDOM from "react-dom";// 導入計數器組件
import Counter from "./components/Counter.jsx";// 使用 render 函數渲染 虛擬DOM
ReactDOM.render(<div>{/* 規定,每個用戶在使用 組件的時候,必須傳遞一個 默認的 數值,作為 組件初始化的 數據 */}<Counter initcount={0}></Counter></div>,document.getElementById("app")
);

(3)/components/Counter.jsx:

import React from "react";
// 注意: prop-types 包的職能跟單一,只提供了 一些常見的 數據類型,用于做類型校驗
import ReactTypes from "prop-types";export default class Counter extends React.Component {constructor(props) {super(props);// 初始化組件,保存的是組件的私有數據this.state = {msg: "ok",count: props.initcount // 把 父組件傳遞過來的 initcount 賦值給子組件 state 中的 count值。這樣的話,就把 count 值改成了可讀可寫的 state 屬性。因此,以后就能實現“點擊 按鈕 ,count 值 + 1”的需求了};}// 在 React 中,使用靜態的 defaultProps 屬性,來設置組件的默認屬性值static defaultProps = {initcount: 0 // 如果外界沒有傳遞 initcount,那么,自己初始化一個數值(比如0)};// 這是創建一個 靜態的 propTypes 對象,在這個對象中,可以把 外界傳遞過來的屬性,做類型校驗static propTypes = {initcount: ReactTypes.number // 使用 prop-types 包,來定義 initcount 為 number 類型};render() {return (<div><div><h3>這是 Counter 計數器組件 </h3><input type="button" value="+1" id="btn" /><p>當前的計數是:{this.state.count}</p></div></div>);// 當 return 執行完畢后, 虛擬DOM創建好了,但是,還沒有掛載到真正的頁面中}// 當組件掛載到頁面上之后,會進入這個生命周期函數,只要進入這個生命周期函數了,必然說明,頁面上,已經有可見的DOM元素了componentDidMount() {// 在這個函數中,我們可以放心的去 操作 頁面上你需要使用的 DOM 元素了。// 也就是說,如果我們想操作DOM元素,最早,只能在 componentDidMount 中進行。document.getElementById("btn").onclick = () => {this.setState({count: this.state.count + 1});};}
}

使用 React 提供的方法,做事件綁定

代碼舉例:

(1)index.html和 (2)main.js 的代碼不變,和上一小段中的代碼一致。

(3)/components/Counter.jsx:

import React from "react";
// 注意: prop-types 包的職能跟單一,只提供了 一些常見的 數據類型,用于做類型校驗
import ReactTypes from "prop-types";export default class Counter extends React.Component {constructor(props) {super(props);// 初始化組件,保存的是組件的私有數據this.state = {msg: "ok",count: props.initcount // 把 父組件傳遞過來的 initcount 賦值給子組件 state 中的 count值。這樣的話,就把 count 值改成了可讀可寫的 state 屬性。因此,以后就能實現“點擊 按鈕 ,count 值 + 1”的需求了};}// 在 React 中,使用靜態的 defaultProps 屬性,來設置組件的默認屬性值static defaultProps = {initcount: 0 // 如果外界沒有傳遞 initcount,那么,自己初始化一個數值(比如0)};// 這是創建一個 靜態的 propTypes 對象,在這個對象中,可以把 外界傳遞過來的屬性,做類型校驗static propTypes = {initcount: ReactTypes.number // 使用 prop-types 包,來定義 initcount 為 number 類型};render() {return (<div><div><h3>這是 Counter 計數器組件 </h3>{/* 這里的 this 指向的是 Counter 組件的實例  */}<input type="button" value="+1" id="btn" onClick={this.myMethod} /><p>當前的計數是:{this.state.count}</p></div></div>);// 當 return 執行完畢后, 虛擬DOM創建好了,但是,還沒有掛載到真正的頁面中}// 點擊事件的方法定義myMethod = () => {// 修改組件的state里面的值this.setState({count: this.state.count + 1});};
}

三、生命周期函數:shouldComponentUpdate()

在 shouldComponentUpdate() 函數中,必須要求返回一個布爾值

需要注意的是:如果返回的值是 false,則不會繼續執行后續的生命周期函數,而是直接退回到了 運行中 的狀態。因為此時,后續的 render 函數并沒有被調用,因此頁面不會被更新,但是組件的 state 狀態,卻被修改了。這種情況,我們也可以這樣理解:如果返回值為 false,此時只是更新了 state 里面的數值,但是并沒有渲染到 DOM節點上。

利用上面這個特性,我們可以來舉個例子。

舉例:實現 Counter 計數器只在偶數情況下更新。

實現思路:在 shouldComponentUpdate() 函數中,如果 state 中 的count 的值為奇數,就 return false;否則就 return true。

代碼實現:(我們在上面的Counter.jsx代碼基礎之上,做添加)

  // 判斷組件是否需要更新shouldComponentUpdate(nextProps, nextState) {// 經過打印測試發現:在 shouldComponentUpdate 中,通過 this.state.count 拿到的值,是上一次的舊數據,并不是當前最新的;// 解決辦法:通過 shouldComponentUpdate 函數的第二個參數 nextState,可以拿到 最新的 state 數據。console.log(this.state.count + " ---- " + nextState.count);// 需求: 如果 state 中的 count 值是偶數,則 更新頁面;如果 count 值 是奇數,則不更新頁面。最終實現的的頁面效果:2,4,6,8,10,12....// return this.state.count % 2 === 0 ? true : falsereturn nextState.count % 2 === 0 ? true : false;}

上面這部分的代碼,和 render() 方法是并列的。我們需要注意里面的注釋,關注 nextState 參數的用法。

四、在js代碼中獲取html標簽的屬性

比如說,如果想獲取 html標簽的 innerHTML 屬性,做法如下:

通過原生 js 獲取:

	document.getElementById('myh3').innerHTML

也可以通過 React 提供的 refs 獲取:

	this.refs.h3.innerHTML

代碼舉例:

(3)/components/Counter.jsx:

import React from "react";
// 注意: prop-types 包的職能跟單一,只提供了 一些常見的 數據類型,用于做類型校驗
import ReactTypes from "prop-types";export default class Counter extends React.Component {constructor(props) {super(props);// 初始化組件,保存的是組件的私有數據this.state = {msg: "ok",count: props.initcount // 把 父組件傳遞過來的 initcount 賦值給子組件 state 中的 count值。這樣的話,就把 count 值改成了可讀可寫的 state 屬性。因此,以后就能實現“點擊 按鈕 ,count 值 + 1”的需求了};}// 在 React 中,使用靜態的 defaultProps 屬性,來設置組件的默認屬性值static defaultProps = {initcount: 0 // 如果外界沒有傳遞 initcount,那么,自己初始化一個數值(比如0)};// 這是創建一個 靜態的 propTypes 對象,在這個對象中,可以把 外界傳遞過來的屬性,做類型校驗static propTypes = {initcount: ReactTypes.number // 使用 prop-types 包,來定義 initcount 為 number 類型};render() {return (<div><div><h3>這是 Counter 計數器組件 </h3>{/* 這里的 this 指向的是 Counter 組件的實例  */}<input type="button" value="+1" id="btn" onClick={this.myMethod} /><h3 id="myh3" ref="mymyh3">當前的計數是:{this.state.count}</h3></div></div>);// 當 return 執行完畢后, 虛擬DOM創建好了,但是,還沒有掛載到真正的頁面中}// 點擊事件的方法定義myMethod = () => {// 修改組件的state里面的值this.setState({count: this.state.count + 1});};// 判斷組件是否需要更新shouldComponentUpdate(nextProps, nextState) {// 需求: 如果 state 中的 count 值是偶數,則 更新頁面;如果 count 值 是奇數,則不更新頁面。最終實現的的頁面效果:2,4,6,8,10,12....// 經過打印測試發現:在 shouldComponentUpdate 中,通過 this.state.count 拿到的值,是上一次的舊數據,并不是當前最新的;// 解決辦法:通過 shouldComponentUpdate 函數的第二個參數 nextState,可以拿到 最新的 state 數據。console.log(this.state.count + " ---- " + nextState.count);// return this.state.count % 2 === 0 ? true : false// return nextState.count % 2 === 0 ? true : false;return true;}// 組件將要更新。此時尚未更新,在進入這個 生命周期函數的時候,內存中的虛擬DOM是舊的,頁面上的 DOM 元素 也是舊的componentWillUpdate() {// 經過打印分析發現:此時頁面上的 DOM 節點,都是舊的,應該慎重操作,因為你可能操作的是舊DOM// console.log(document.getElementById('myh3').innerHTML)console.log(this.refs.mymyh3.innerHTML);}// 組件完成了更新。此時,state 中的數據、虛擬DOM、頁面上的DOM,都是最新的,此時,你可以放心大膽的去操作頁面了componentDidUpdate() {console.log(this.refs.mymyh3.innerHTML);}
}

上方代碼中,componentWillUpdate() 和 componentDidUpdate() 方法里的代碼,就是我們這一段要舉的例子。

需要注意的是,<h3 id="myh3" ref="mymyh3">這部分代碼中,屬性名只能小寫,不能大寫。

工程文件:

  • ReactDemo.zip

五、生命周期函數:componentWillReceiveProps()

當子組件第一次被渲染到頁面上的時候,不會觸發這個 函數。

只有當父組件中,通過 某些 事件,重新修改了 傳遞給 子組件的 props 數據之后,才會觸發 componentWillReceiveProps。

代碼舉例:

(1)index.html:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head><body><!-- 容器,通過 React 渲染得到的 虛擬DOM,會呈現到這個位置 --><div id="app"></div>
</body></html>

(2)main.js:(引入組件)

// JS打包入口文件
// 1. 導入包
import React from "react";
import ReactDOM from "react-dom";import MyParent from "./components/TestReceiveProps.jsx";// 使用 render 函數渲染 虛擬DOM
ReactDOM.render(<div><MyParent></MyParent></div>,document.getElementById("app")
);

(3)TestReceiveProps.jsx:(組件的定義)

import React from "react";// 父組件
export default class Parent extends React.Component {constructor(props) {super(props);this.state = {msg: "這是父組件中的 msg 消息"};}render() {return (<div><h1>這是父組件</h1><inputtype="button"value="點擊修改父組件的 MSG"onClick={this.changeMsg}/><hr />{/* 在父組件 Parent 中引用子組件 Son */}<Son pmsg={this.state.msg} /></div>);}changeMsg = () => {this.setState({msg: "修改組件的msg為新的值"});};
}// 子組件
class Son extends React.Component {constructor(props) {super(props);this.state = {};}render() {return (<div><h3>這是子組件 --- {this.props.pmsg}</h3></div>);}// 組件將要接收外界傳遞過來的新的 props 屬性值// 當子組件第一次被渲染到頁面上的時候,不會觸發這個 函數;// 只有當 父組件中,通過 某些 事件,重新修改了 傳遞給 子組件的 props 數據之后,才會觸發 componentWillReceivePropscomponentWillReceiveProps(nextProps) {// console.log('被觸發了!');// 注意: 在 componentWillReceiveProps 被觸發的時候,如果我們使用 this.props 來獲取屬性值,這個屬性值,不是最新的,是上一次的舊屬性值// 如果想要獲取最新的屬性值,需要通過 componentWillReceiveProps 的參數列表來獲取console.log(this.props.pmsg + " ---- " + nextProps.pmsg);}
}

上方代碼中,我們在組件 Parent 中引入了子組件 Son。重點注意 componentWillReceiveProps()函數 的注釋部分。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/81064.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/81064.shtml
英文地址,請注明出處:http://en.pswp.cn/web/81064.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

redis 進行緩存實戰-18

使用 Redis 進行緩存 Redis 通常被認為只是一個數據存儲&#xff0c;但它的速度和內存中特性使其成為緩存的絕佳選擇。緩存是一種技術&#xff0c;通過將經常訪問的數據存儲在快速的臨時存儲位置來提高應用程序性能。通過使用 Redis 作為緩存&#xff0c;您可以顯著減少主數據…

【Nginx學習筆記】:Fastapi服務部署單機Nginx配置說明

服務部署單機Nginx配置說明 服務.conf配置文件&#xff1a; upstream asr_backend {server 127.0.0.1:8010; }server {listen 80;server_name your_domain.com;location / {proxy_pass http://localhost:8000;proxy_set_header Host $host;proxy_set_header X-Real-IP $remot…

Qt網絡編程

前言 Qt為了支持跨平臺&#xff0c;對系統網絡編程的API&#xff08;socket API&#xff09;也進行了重新分裝。 實際Qt中進行網絡編程也不一定使用Qt封裝的網絡API&#xff0c;也有可能使用的是系統原生API或者其他第三方框架的API。 若要使用Qt中的網絡編程的API&#xff…

矩陣短劇系統:如何用1個后臺管理100+小程序?技術解析與實戰應用

引言&#xff1a;短劇行業的效率革命 2025年&#xff0c;短劇市場規模已突破千億&#xff0c;但傳統多平臺運營模式面臨重復開發成本高、用戶數據分散、內容同步效率低等痛點。行業亟需一種既能降本增效又能聚合流量的解決方案——“矩陣短劇系統”。通過“1個后臺管理100小程…

嵌入式STM32學習——ESP8266 01S的基礎介紹

簡介 ESP8266 系列模組是深圳市安信可科技有限公司開發的一系列基于樂鑫ESP8266EX的低功耗UART-WiFi芯片模組&#xff0c;可以方便地進行二次開發&#xff0c;接入云端服務&#xff0c;實現手機3/4G全球隨時隨地的控制&#xff0c;加速產品原型設計。 模塊核心處理器 ESP8266 在…

form-create-designer中$inject參數的數據結構及各項屬性說明

FcDesigner 是一款基于Vue的開源低代碼可視化表單設計器工具&#xff0c;通過數據驅動表單渲染。可以通過拖拽的方式快速創建表單&#xff0c;提高開發者對表單的開發效率&#xff0c;節省開發者的時間。并廣泛應用于在政務系統、OA系統、ERP系統、電商系統、流程管理等領域。 …

Jasypt概述及整合SpringBoot實現敏感數據加密

前言 在實際開發中&#xff0c;Spring Boot應用的配置文件中經常包含數據庫密碼、API密鑰等敏感信息。如果這些信息以明文形式存儲&#xff0c;會帶來嚴重的安全隱患。本文將詳細介紹如何使用Jasypt&#xff08;Java Simplified Encryption&#xff09;對Spring Boot配置文件中…

Better Faster Large Language Models via Multi-token Prediction 原理

目錄 模型結構&#xff1a; Memory-efficient implementation&#xff1a; 實驗&#xff1a; 1. 在大規模模型上效果顯著&#xff1a; 2. 在不同類型任務上的效果&#xff1a; 為什么MLP對效果有提升的幾點猜測&#xff1a; 1. 并非所有token對生成質量的影響相同 2. 關…

git merge解沖突后,add、continue提交

git merge解沖突后&#xff0c;add、continue提交 git merge操作沖突后&#xff0c;需要手動解沖突&#xff0c;解完沖突后&#xff0c;需要: git add . 然后&#xff0c;進入一般的正常git代碼提交流程。 git合并‘merge’其他分支的個別文件到當前branch_gitbash 合并branc…

3.8.1 利用RDD實現詞頻統計

在本次實戰中&#xff0c;我們通過Spark的RDD實現了詞頻統計功能。首先&#xff0c;準備了包含單詞的文件并上傳至HDFS。接著&#xff0c;采用交互式方式逐步完成詞頻統計&#xff0c;包括創建RDD、單詞拆分、映射為二元組、按鍵歸約以及排序等操作。此外&#xff0c;還通過創建…

應對進行性核上性麻痹,健康護理鑄就溫暖防線

進行性核上性麻痹&#xff08;PSP&#xff09;是一種罕見的神經退行性疾病&#xff0c;主要影響患者的運動、平衡及吞咽等功能。針對這類患者&#xff0c;有效的健康護理對提升其生活質量、延緩病情發展至關重要。 在日常生活護理方面&#xff0c;由于患者存在平衡障礙和肌肉僵…

融合蛋白質語言模型和圖像修復模型,麻省理工與哈佛聯手提出PUPS ,實現單細胞級蛋白質定位

蛋白質亞細胞定位&#xff08;subcellular localization of a protein&#xff09;是指蛋白質在細胞結構中具體的定位情況&#xff0c; 這對蛋白質行使其生物學功能至關重要。舉個簡單例子&#xff0c;如果把細胞想象成一個龐大的企業&#xff0c;其中細胞核、線粒體、細胞膜等…

lanqiaoOJ 4330:歐拉函數模板

【題目來源】 https://www.lanqiao.cn/problems/4330/learning/ 【問題描述】 這是一道模板題。 首先給出歐拉函數的定義&#xff1a;即 φ(n) 表示的是小于等于 n 的數中和 n 互質的數的個數。 比如說 φ(6)2&#xff0c;當 n 是質數的時候&#xff0c;顯然有φ(n)n-1。 【題…

無人機電子防抖技術要點概述!

一、技術要點 1. 傳感器數據融合 電子防抖需結合陀螺儀、加速度計、視覺傳感器等多源數據&#xff0c;實時檢測無人機的姿態變化和振動頻率。例如&#xff0c;IMU&#xff08;慣性測量單元&#xff09;通過加速度計和陀螺儀測量飛行器的姿態和運動狀態&#xff0c;結合視覺感…

Win10 安裝單機版ES(elasticsearch),整合IK分詞器和安裝Kibana

一. 先查看本機windows是否安裝了ES(elasticsearch)&#xff0c;檢查方法如下&#xff1a; 檢查進程 按 Ctrl Shift Esc 組合鍵打開 “任務管理器”。在 “進程” 選項卡中&#xff0c;查看是否有 elasticsearch 相關進程。如果有&#xff0c;說明系統安裝了 ES。 檢查端口…

BIO、NIO、AIO 的區別與實戰應用解析

導語&#xff1a; BIO、NIO 和 AIO 是后端面試中的經典話題&#xff0c;尤其在高并發、高性能場景下更是重中之重。本文將從面試官視角出發&#xff0c;深入剖析三者的區別、典型題目和實戰解答&#xff0c;助你掌握答題技巧&#xff0c;輕松拿下這一高頻考點&#xff01; 一、…

電腦風扇轉速不正常的原因

一、硬件故障或接觸問題 1. 風扇本身損壞 扇葉卡頓或軸承磨損&#xff1a;灰塵堆積、異物纏繞&#xff08;如頭發、線纜&#xff09;會導致扇葉轉動阻力增大&#xff0c;發出異響并轉速下降&#xff1b;軸承潤滑脂干涸或老化會引起風扇噪音大、轉速不穩定。電機故障&#xff…

運維打鐵:生產服務器用戶權限管理方案全解析

文章目錄 一、引言二、方案設計2.1 權限模型選擇2.2 角色定義2.3 權限分配2.4 用戶與角色關聯 三、相關代碼注釋&#xff08;以 Linux 系統為例&#xff09;3.1 用戶創建與角色分配腳本3.2 權限設置腳本 四、常見問題解決4.1 用戶無法登錄4.2 用戶權限不足4.3 權限文件修改后不…

在tp6模版中加減法

實際項目中&#xff0c;我們經常需要標簽變量加減運算的操作。但是&#xff0c;在ThinkPHP中&#xff0c;并不支持模板變量直接運算的操作。幸運的是&#xff0c;它提供了自定義函數的方法&#xff0c;我們可以利用自定義函數解決&#xff1a;ThinkPHP模板自定義函數語法如下&a…

Fastjson利用鏈JdbcRowSetImpl分析

首先創建客戶端 package com.yq1ng.vul;import com.alibaba.fastjson.JSON;/*** FastJsonTest** author yq1ng* date 2021/12/29 19:45* since 1.0.0*/ public class FastJsonTest {public static void main(String[] args) {String ser "{\"type\":\"co…