摘要:給賦值也是構(gòu)造函數(shù)的工作之一。在的構(gòu)造函數(shù)中,還給兩個(gè)成員函數(shù)綁定了當(dāng)前的執(zhí)行環(huán)境,因?yàn)榉绞絼?chuàng)建的組件并不自動(dòng)給我們綁定到當(dāng)前實(shí)例對(duì)象。我們可以利用的功能,避免判斷邏輯這種充斥在構(gòu)造函數(shù)之中,讓代碼更優(yōu)。
React系列---React(一)初識(shí)React
React系列---React(二)組件的prop和state
React系列---React(三)組件的生命周期
組件是React的基石,所有的React應(yīng)用程序都是基于組件的。基于組件的應(yīng)用開(kāi)發(fā)是廣泛使用的軟件開(kāi)發(fā)模式,用分而治之的方法,把一個(gè)大的應(yīng)用分解成若干小的組件,每個(gè)組件只關(guān)注某個(gè)特定功能,但是把組件組合起來(lái),就能構(gòu)成一個(gè)功能龐大的應(yīng)用。
React組件的數(shù)據(jù)分為兩種,prop和state,無(wú)論prop或者state的改變,都可能引發(fā)組件的重新渲染。prop是組件對(duì)外接口,state是組件內(nèi)部狀態(tài)。
第一個(gè)組件用create-react-app工具,初始化一個(gè)React項(xiàng)目:
npm create-react-app react-component-demo
創(chuàng)建一個(gè)可以計(jì)算點(diǎn)擊數(shù)的組件:
/src/ClickCounter.js:
import React from "react"; class ClickCounter extends React.Component { constructor(props) { super(props); this.onClickButton = this.onClickButton.bind(this); this.state = {count: 0}; } onClickButton() { this.setState({count: this.state.count + 1}); } render() { return (); }; } export default ClickCounter;Click Count: {this.state.count}
修改/src/index.js:
import React from "react"; import ReactDOM from "react-dom"; import ClickCounter from "./ClickCounter"; ReactDOM.render(, document.getElementById("root"));
運(yùn)行React項(xiàng)目
npm run start
點(diǎn)擊按鈕,數(shù)字會(huì)隨之增加。恭喜你,已經(jīng)構(gòu)建了一個(gè)有交互的組件!
我們還可以在React組件中定義樣式。修改ClickCounter組件的render函數(shù):
render() { const counterStyle = { margin: "16px" }; return (組件的prop); };Click Count: {this.state.count}
React組件通過(guò)定義自己能夠接受的prop就定義了自己對(duì)外公共接口。外部世界通過(guò)prop和組件對(duì)話。
給prop賦值從外部世界看prop的使用:
上面的例子使用了名為SampleButton的組件實(shí)例。React組件的prop所能支持的類型除了字符串,還可以是任何一種JavaScript語(yǔ)言支持的數(shù)據(jù)類型。當(dāng)prop的類型不是字符串時(shí),再JSX中必須用花括號(hào){}把值包裹,所以style的值有兩層花括號(hào),外層代表是JSX的語(yǔ)法,內(nèi)層代表這是個(gè)對(duì)象常量。
React組件要反饋數(shù)據(jù)給外部世界,也是用prop,因?yàn)閜rop類型也可以是函數(shù),函數(shù)類型的prop等于讓父組件交給子組件一個(gè)回調(diào)函數(shù),子組件在恰當(dāng)?shù)臅r(shí)機(jī)調(diào)用函數(shù)的prop,就可以把信息傳遞給外部世界。
為了演示,我們構(gòu)造一個(gè)應(yīng)用包含兩種組件,ControlPanel父組件,然后若干個(gè)Counter子組件。對(duì)于Counter組件,父組件ControlPanel就是外部世界:
class ControlPanel extends React.Component { render() { return (); } }
React要求render只能返回一個(gè)元素,所以我們用div包裹了3個(gè)子組件。
每個(gè)Counter組件使用了caption和initValue兩個(gè)prop。ControlPanel通過(guò)caption的prop傳遞給Counter組件實(shí)例說(shuō)明文字,通過(guò)initValue的prop傳遞給Count組件一個(gè)初始的計(jì)數(shù)值。
讀取prop值看下Counter組件內(nèi)部是如何接收prop的:
class Counter extends React.Component { constructor(props) { super(props); this.onClickIncrementButton = this.onClickIncrementButton.bind(this); this.onClickDecrementButton = this.onClickDecrementButton.bind(this); this.state = { count: props.initValue || 0 }; } }
如果組件需要定義自己的構(gòu)造函數(shù),構(gòu)造函數(shù)第一行一定要通過(guò)super調(diào)用父類React.Component的構(gòu)造函數(shù)。給this.props賦值也是React.Component構(gòu)造函數(shù)的工作之一。
在Counter的構(gòu)造函數(shù)中,還給兩個(gè)成員函數(shù)綁定了當(dāng)前this的執(zhí)行環(huán)境,因?yàn)镋S6方式創(chuàng)建的組件并不自動(dòng)給我們綁定this到當(dāng)前實(shí)例對(duì)象。
在其他函數(shù)中則可以通過(guò)this.props訪問(wèn)傳入的值,看一下render函數(shù):
render() { const {caption} = this.props; // ES6的解構(gòu)賦值 return (propTypes檢查{caption} count: {this.state.count}); };
在ES6方法定義的組件中,可以通過(guò)增加類的propTypes屬性來(lái)定義prop規(guī)格。在運(yùn)行和靜態(tài)代碼檢查時(shí),都可以根據(jù)propTypes判斷外部世界是否正確地使用了組件的屬性。
增加Counter組件的propTypes定義:
Counter.propTypes = { caption: PropTypes.string.isRequired, initValue: PropTypes.number };
開(kāi)發(fā)過(guò)程中,定義propTypes代碼可以避免犯錯(cuò),但是在發(fā)布產(chǎn)品時(shí),可以用babel-react-optimize工具自動(dòng)去除propTypes,這樣部署到產(chǎn)品環(huán)境的代碼就會(huì)更優(yōu)。
組件的state驅(qū)動(dòng)組件渲染的除了prop,還有state,state代表組件內(nèi)部狀態(tài)。由于React組件禁止修改傳入的prop,所以當(dāng)組件需要記錄自身的數(shù)據(jù)變化時(shí),就要使用state。
在Counter組件中,初始計(jì)數(shù)可以通過(guò)initValue這個(gè)prop指定。當(dāng)用戶點(diǎn)擊“+”和“-”改變計(jì)數(shù)時(shí),就要Counter組件自己通過(guò)state來(lái)存儲(chǔ)了。
通常在構(gòu)造函數(shù)的結(jié)尾處初始化state,就如上面的Counter:
constructor(props) { ... this.state = { count: props.initValue || 0 }; }
由于在PropType聲明中沒(méi)有用isRequired,我們需要在代碼中判斷給定的prop值是否存在,不存在則給一個(gè)默認(rèn)值。我們可以利用React的defaultProps功能,避免判斷邏輯這種充斥在構(gòu)造函數(shù)之中,讓代碼更優(yōu)。
給Counter組件添加defaultProps代碼:
Counter.defaultProps = { initValue: 0 };
構(gòu)造函數(shù)就可以簡(jiǎn)化了:
constructor(props) { ... this.state = { count: props.initValue }; }讀取和更新state
通過(guò)給button的onClick屬性掛載點(diǎn)擊事件處理函數(shù),我們可以改變組件的state,以點(diǎn)擊“+”按鈕的響應(yīng)函數(shù)為例:
onClickIncrementButton() { this.setState({count: this.state.count + 1}); }
通過(guò)this.state可以讀取到組件的當(dāng)前state。注意的是,改變state必須使用this.setState函數(shù),而不能直接修改this.state。如果你違反這個(gè)操作,瀏覽器Console會(huì)告警。
直接修改this.state的值,只是野蠻的修改了state,卻沒(méi)有驅(qū)動(dòng)組件重新渲染,新的值當(dāng)然也不會(huì)反應(yīng)在界面上。而this.setState()函數(shù)所做的事情,就是改變this.state的值后再驅(qū)動(dòng)組件重新渲染。
無(wú)狀態(tài)函數(shù)式組件沒(méi)有內(nèi)部state,不需要組件生命周期函數(shù)。可以用純函數(shù)的形式來(lái)表達(dá)。它做的事情只是根據(jù)輸入來(lái)展示組件,沒(méi)有其他副作用。可以把這種組件稱為無(wú)狀態(tài)函數(shù)式組件(stateless functional component)。
import React from "react"; // 用一個(gè)純函數(shù)表示 const Hobby = (props) =>
創(chuàng)建盡量多的無(wú)狀態(tài)組件,這些組件唯一關(guān)心的就是渲染數(shù)據(jù)。而在最外層,應(yīng)該有一個(gè)包含state的父級(jí)別組件,用于處理各種事件、交流邏輯、修改state。對(duì)應(yīng)的子組件要關(guān)心的只是傳入的屬性而已。
state應(yīng)該包含組件的事件回調(diào)函數(shù)可能引發(fā)UI更新的這類數(shù)據(jù)。在實(shí)際的項(xiàng)目中,應(yīng)該是輕量化的JSON數(shù)據(jù),盡量把數(shù)據(jù)的表現(xiàn)設(shè)計(jì)到最小,更多的數(shù)據(jù)可以在render中通過(guò)各種計(jì)算得到。
prop和state對(duì)比prop用于定義外部接口,state用于記錄內(nèi)部狀態(tài);
prop的賦值在外部世界使用組件時(shí),state的賦值在組件內(nèi)部;
組件不應(yīng)該改變prop的值,而state的存在的目的就是讓組件來(lái)改變的。
DOM操作大多數(shù)情況下,不需要操作DOM去更新UI,應(yīng)使用setState。但是有些情況確實(shí)需要訪問(wèn)一些DOM(如表單的值),那么可采用refs方式來(lái)獲得DOM節(jié)點(diǎn)。只需要加個(gè)ref屬性,然后通過(guò)this.refs.name來(lái)獲得對(duì)應(yīng)的DOM結(jié)構(gòu)。
示例Profile組件:
render() { return (...) }
在button上添加事件,取得input的值,添加到state的值里面:
addHobbyCallback() { // 用this.refs.name來(lái)取得DOM節(jié)點(diǎn) let hobbyInput = this.refs.hobby; let val = hobbyInput.value; if (val) { let hobbies = this.state.hobbies; // 添加值到數(shù)組 hobbies = [...hobbies, val]; // 更新state, 刷新UI this.setState({ hobbies }, () => { hobbyInput.value = ""; }); } }
React系列---React(一)初識(shí)React
React系列---React(二)組件的prop和state
React系列---React(三)組件的生命周期
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/83674.html
摘要:用于規(guī)范的類型與必需的狀態(tài)。表示由組件更改的數(shù)據(jù),通常是通過(guò)與用戶的交互來(lái)更改的。為了實(shí)現(xiàn)的修改,需要注冊(cè)事件處理程序到相應(yīng)的元素上。當(dāng)事件發(fā)生時(shí),將更新后的值是從中檢索,并通知組件。通常情況下,該函數(shù)初始化狀態(tài)使用,,或其他數(shù)據(jù)存儲(chǔ)。 前言 上一篇文章中,我們講到了JSX的一些用法和注意事項(xiàng),這次我們來(lái)講react中最基礎(chǔ)也是特別重要的內(nèi)容:組件。這篇文章包含組件的以下內(nèi)容:狀態(tài)、屬...
摘要:組件裝載過(guò)程裝載過(guò)程依次調(diào)用的生命周期函數(shù)中每個(gè)類的構(gòu)造函數(shù),創(chuàng)造一個(gè)組件實(shí)例,當(dāng)然會(huì)調(diào)用對(duì)應(yīng)的構(gòu)造函數(shù)。組件需要構(gòu)造函數(shù),是為了以下目的初始化,因?yàn)樯芷谥腥魏魏瘮?shù)都有可能訪問(wèn),構(gòu)造函數(shù)是初始化的理想場(chǎng)所綁定成員函數(shù)的環(huán)境。 React系列---React(一)初識(shí)ReactReact系列---React(二)組件的prop和stateReact系列---之React(三)組件的生...
摘要:當(dāng)真正執(zhí)行狀態(tài)修改時(shí),依賴的并不能保證是最新的,因?yàn)闀?huì)把多次的修改合并成一次,這時(shí),還是等于這幾次修改發(fā)生前的。下篇預(yù)告深入系列組件的生命周期新書推薦進(jìn)階之路作者徐超畢業(yè)于浙江大學(xué),碩士,資深前端工程師,長(zhǎng)期就職于能源物聯(lián)網(wǎng)公司遠(yuǎn)景智能。 文:徐超,《React進(jìn)階之路》作者授權(quán)發(fā)布,轉(zhuǎn)載請(qǐng)注明作者及出處 React 深入系列3:Props 和 State React 深入系列,深...
摘要:深入系列,深入講解了中的重點(diǎn)概念特性和模式等,旨在幫助大家加深對(duì)的理解,以及在項(xiàng)目中更加靈活地使用。下篇預(yù)告深入系列組件的生命周期我的新書進(jìn)階之路已上市,請(qǐng)大家多多支持鏈接京東當(dāng)當(dāng) React 深入系列,深入講解了React中的重點(diǎn)概念、特性和模式等,旨在幫助大家加深對(duì)React的理解,以及在項(xiàng)目中更加靈活地使用React。 React 的核心思想是組件化的思想,而React 組件的定...
摘要:在這篇文章中,我們就要實(shí)現(xiàn)的組件功能。這篇文章的代碼從零開(kāi)始實(shí)現(xiàn)系列是前端最受歡迎的框架之一,解讀其源碼的文章非常多,但是我想從另一個(gè)角度去解讀從零開(kāi)始實(shí)現(xiàn)一個(gè),從層面實(shí)現(xiàn)的大部分功能,在這個(gè)過(guò)程中去探索為什么有虛擬為什么這樣設(shè)計(jì)等問(wèn)題。 前言 在上一篇文章JSX和虛擬DOM中,我們實(shí)現(xiàn)了基礎(chǔ)的JSX渲染功能,但是React的意義在于組件化。在這篇文章中,我們就要實(shí)現(xiàn)React的組件功...
閱讀 3172·2021-09-22 15:05
閱讀 2748·2019-08-30 15:56
閱讀 1054·2019-08-29 17:09
閱讀 792·2019-08-29 15:12
閱讀 2076·2019-08-26 11:55
閱讀 3037·2019-08-26 11:52
閱讀 3370·2019-08-26 10:29
閱讀 1374·2019-08-23 17:19