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