摘要:我們可以使用函數(shù)構(gòu)造函數(shù)將我們的組件轉(zhuǎn)換為狀態(tài)什么是函數(shù)構(gòu)造函數(shù)在中,函數(shù)是一個(gè)在創(chuàng)建對(duì)象時(shí)運(yùn)行的函數(shù)。我們將使用構(gòu)造函數(shù)方法在對(duì)象創(chuàng)建時(shí)正確運(yùn)行對(duì)象時(shí)設(shè)置實(shí)例變量。每當(dāng)一個(gè)有一個(gè)屬性被設(shè)置時(shí),它會(huì)在該字段改變的每個(gè)時(shí)間調(diào)用函數(shù)。
本文轉(zhuǎn)載自:眾成翻譯
譯者:iOSDevLog
鏈接:http://www.zcfy.cc/article/3823
原文:https://www.fullstackreact.com/30-days-of-react/day-10/
今天,我們將介紹如何添加交互性到我們的應(yīng)用,使其具有吸引力和交互性。
通過(guò)這一點(diǎn),我們構(gòu)建了少數(shù)幾個(gè)組件,而沒(méi)有添加用戶交互。 今天我們將要改變它。
用戶交互瀏覽器是事件驅(qū)動(dòng)的應(yīng)用程序。 用戶在瀏覽器中進(jìn)行的一切都會(huì)觸發(fā)一個(gè)事件,從點(diǎn)擊按鈕,甚至只是移動(dòng)鼠標(biāo)。 在簡(jiǎn)單的JavaScript中,我們可以監(jiān)聽(tīng)這些事件并附加一個(gè)JavaScript函數(shù)與它們進(jìn)行交互。
例如,我們可以使用JS附加一個(gè)函數(shù)到mousemove瀏覽器事件:
export const go = () => { const ele = document.getElementById("mousemove"); ele.innerHTML = "Move your mouse to see the demo"; ele.addEventListener("mousemove", function(evt) { const { screenX, screenY } = evt; ele.innerHTML = "Mouse is at: X: " + screenX + ", Y: " + screenY + ""; }) }
這導(dǎo)致以下行為:
將鼠標(biāo)移到該文本上
然而,在React中,我們不必在原始JavaScript中與瀏覽器的事件循環(huán)進(jìn)行交互,因?yàn)镽eact為我們使用props處理事件提供了一種方法。
例如,要從React上面的(相當(dāng)不起眼的)演示中收聽(tīng)mousemove 事件,我們將設(shè)置onMouseMove (請(qǐng)注意事件名稱是駝峰命名的)。
console.log(evt)}> Move the mouse
React提供了很多props ,我們可以設(shè)置監(jiān)聽(tīng)不同的瀏覽器事件,例如點(diǎn)擊,觸摸,拖動(dòng),滾動(dòng),選擇事件等等(參見(jiàn)事件文檔列出所有這些)。
要看看其中的一些在行動(dòng)中,以下是一些小的演示,一些props ,我們可以傳遞我們的元素。 列表中的每個(gè)文本元素設(shè)置其列出的屬性。 嘗試使用列表查看事件在元素中的調(diào)用和處理方式。
我們將在我們的應(yīng)用中使用 onClick 屬性相當(dāng)多,所以熟悉它是一個(gè)好主意。 在我們的活動(dòng)列表標(biāo)題中,我們有一個(gè)搜索圖標(biāo),我們還沒(méi)有與顯示一個(gè)搜索框關(guān)聯(lián)起來(lái)。
我們_想要_的交互是在用戶點(diǎn)擊搜索圖標(biāo)時(shí)顯示搜索。 回想一下,我們的Header組件是這樣實(shí)現(xiàn)的:
class Header extends React.Component { constructor(props) { super(props); this.state = { searchVisible: false } } // toggle visibility when run on the state showSearch() { this.setState({ searchVisible: !this.state.searchVisible }) } render() { // Classes to add to the element let searchInputClasses = ["searchInput"]; // Update the class array if the state is visible if (this.state.searchVisible) { searchInputClasses.push("active"); } return () } }{this.props.title} {/* Adding an onClick handler to call the showSearch button */}
當(dāng)用戶點(diǎn)擊 元素時(shí),我們需要運(yùn)行一個(gè)函數(shù)來(lái)更新組件的狀態(tài),以便searchInputClasses對(duì)象更新。 使用onClick處理程序,這很簡(jiǎn)單。
我們讓這個(gè)組件有狀態(tài)(它需要跟蹤搜索字段是否應(yīng)該顯示)。 我們可以使用constructor() 函數(shù)(構(gòu)造函數(shù))將我們的組件轉(zhuǎn)換為狀態(tài):
class Header extends React.Component { constructor(props) { super(props); this.state = { searchVisible: false } } // ... }
什么是constructor函數(shù)(構(gòu)造函數(shù))?在JavaScript中,constructor 函數(shù)是一個(gè)在創(chuàng)建對(duì)象時(shí)運(yùn)行的函數(shù)。它返回對(duì)創(chuàng)建實(shí)例的prototype的Object函數(shù)的引用。
在純英文中,構(gòu)造函數(shù)是JavaScript運(yùn)行時(shí)創(chuàng)建新對(duì)象時(shí)運(yùn)行的函數(shù)。我們將使用構(gòu)造函數(shù)方法在對(duì)象創(chuàng)建時(shí)正確運(yùn)行對(duì)象時(shí)設(shè)置實(shí)例變量。
當(dāng)使用ES6類語(yǔ)法創(chuàng)建對(duì)象時(shí),我們必須在任何其他方法之前調(diào)用super() 方法。調(diào)用super() 函數(shù)調(diào)用父類的 constructor() 函數(shù)。我們將使用_相同參數(shù)_調(diào)用它,因?yàn)槲覀冾惖?constructor() 函數(shù)被調(diào)用。
當(dāng)用戶點(diǎn)擊按鈕時(shí),我們將要更新?tīng)顟B(tài)來(lái)表示searchVisible 標(biāo)志被更新。由于我們希望用戶能夠第二次點(diǎn)擊搜索圖標(biāo)后關(guān)閉/隱藏 字段,所以我們將_切換_該狀態(tài),而不是將其設(shè)置為true。
我們創(chuàng)建這個(gè)方法來(lái)綁定我們的點(diǎn)擊事件:
class Header extends React.Component { // ... showSearch() { this.setState({ searchVisible: !this.state.searchVisible }) } // ... }
最后,我們可以在icon元素上附加一個(gè)點(diǎn)擊處理程序(使用onClick 屬性)來(lái)調(diào)用我們新的 showSearch() 方法。 我們的 Header組件的整個(gè)更新的源代碼如下所示:
class Header extends React.Component { constructor(props) { super(props); this.state = { searchVisible: false } } // toggle visibility when run on the state showSearch() { this.setState({ searchVisible: !this.state.searchVisible }) } render() { // Classes to add to the element let searchInputClasses = ["searchInput"]; // Update the class array if the state is visible if (this.state.searchVisible) { searchInputClasses.push("active"); } return ({this.props.title} {/* Adding an onClick handler to call the showSearch button */}) } }
嘗試點(diǎn)擊搜索圖標(biāo)并觀看輸入字段出現(xiàn)并消失(動(dòng)畫(huà)效果由CSS動(dòng)畫(huà)處理)。
輸入事件無(wú)論何時(shí)在React中構(gòu)建表單,我們將使用React提供的輸入事件。最值得注意的是,我們最常使用 onSubmit() 和onChange()屬性。
我們更新我們的搜索框演示,以便在更新時(shí)捕獲搜索字段內(nèi)的文本。每當(dāng)一個(gè) 有一個(gè) onChange()屬性被設(shè)置時(shí),它會(huì)在該字段_改變_的每個(gè)時(shí)間調(diào)用函數(shù)。當(dāng)我們點(diǎn)擊它并開(kāi)始輸入時(shí),該函數(shù)將被調(diào)用。
使用這個(gè)屬性,我們可以捕捉到我們這個(gè)字段的價(jià)值。
讓我們創(chuàng)建一個(gè)新的子組件來(lái)包含一個(gè) 元素而不是更新我們的
我們創(chuàng)建一個(gè)我們稱之為SearchForm的新組件。這個(gè)新組件是一個(gè)有狀態(tài)的組件,因?yàn)槲覀冃枰3炙阉鬏斎氲闹担ǜ櫵淖兓?/p>
class SearchForm extends React.Component { // ... constructor(props) { super(props); this.state = { searchText: "" } } // ... }
現(xiàn)在,我們已經(jīng)在
class SearchForm extends React.Component { // ... render() { const { searchVisible } = this.state; let searchClasses = ["searchInput"] if (searchVisible) { searchClasses.push("active") } return (); } }
請(qǐng)注意,我們?cè)谖覀兊?字段上丟失了樣式。 由于我們不再在我們的新 組件中具有searchVisible狀態(tài),所以我們不能再使用它來(lái)對(duì)其進(jìn)行風(fēng)格化了。 _無(wú)論如何_,我們可以從我們的Header組件傳遞一個(gè)支持,該組件告訴SearchForm將輸入渲染為可見(jiàn)。
我們定義searchVisible 屬性(當(dāng)然使用React.PropTypes),并更新render函數(shù)以使用新的prop值來(lái)顯示(或隱藏)搜索。 我們還將為字段的可見(jiàn)性設(shè)置一個(gè)默認(rèn)值為false(因?yàn)槲覀兊?b>Header顯示/隱藏它很好):
class SearchForm extends React.Component { static propTypes = { onSubmit: React.PropTypes.func.isRequired, searchVisible: React.PropTypes.bool } // ... }
現(xiàn)在我們?cè)?元素上有我們的樣式,讓我們添加用戶在搜索框中鍵入的功能,我們將要捕獲搜索字段的值。 我們可以通過(guò)將onChange參數(shù)附加到 元素上來(lái)實(shí)現(xiàn)這個(gè)工作流,并在每次更改 元素時(shí)傳遞一個(gè)函數(shù)來(lái)調(diào)用它。
class SearchForm extends React.Component { // ... updateSearchInput(e) { const val = e.target.value; this.setState({ searchText: val }); } // ... render() { const { searchVisible } = this.state; let searchClasses = ["searchInput"] if (searchVisible) { searchClasses.push("active") } return (); } }
當(dāng)我們鍵入字段時(shí),將會(huì)調(diào)用updateSearchInput() 函數(shù)。 我們將通過(guò)更新?tīng)顟B(tài)來(lái)跟蹤表單的值。 在updateSearchInput() 函數(shù)中,我們可以直接調(diào)用this.setState() 來(lái)更新組件的狀態(tài)。
該值在event對(duì)象的目標(biāo)上保存為`event.target.value"。
class SearchForm extends React.Component { // ... updateSearchInput(e) { const val = e.target.value; this.setState({ searchText: val }); } // ... }
控制與不受控制我們正在創(chuàng)建所謂的不受控制的組件,因?yàn)槲覀儧](méi)有設(shè)置 元素的值。 我們現(xiàn)在不能對(duì)輸入的文本值提供任何驗(yàn)證或后處理。
如果我們要驗(yàn)證字段或操作 組件的值,我們將必須創(chuàng)建一個(gè)所謂的控件組件,這真的只是意味著我們使用value"傳遞一個(gè)值 屬性。 受控組件版本的render()` 函數(shù)將如下所示:
class SearchForm extends React.Component { render() { return ( ); } }
到目前為止,我們無(wú)法真正提交表單,所以我們的用戶無(wú)法真正搜索。 我們來(lái)改變一下 我們需要將component包含在一個(gè)DOM元素中,這樣我們的用戶可以按回車鍵提交表單。 我們可以使用 元素上的onSubmit支持來(lái)捕獲表單提交。
我們來(lái)更新render()函數(shù)來(lái)反映這個(gè)變化。
class SearchForm extends React.Component { // ... submitForm(e) { e.preventDefault(); const {searchText} = this.state; this.props.onSubmit(searchText); } // ... render() { const { searchVisible } = this.props; let searchClasses = ["searchInput"] if (searchVisible) { searchClasses.push("active") } return (); } }
我們立即在submitForm()函數(shù)上調(diào)用event.preventDefault()。這將阻止瀏覽器冒泡,從而使整個(gè)頁(yè)面的默認(rèn)行為重新加載(瀏覽器提交表單時(shí)的默認(rèn)功能)。
現(xiàn)在當(dāng)我們鍵入 字段并按回車鍵,submitForm() 函數(shù)被調(diào)用的事件對(duì)象。
那么好的,我們可以提交表單和內(nèi)容,但是什么時(shí)候我們實(shí)際上進(jìn)行搜索?為了演示目的,我們將把搜索文本傳遞給父子組件鏈,以便 Header 可以決定搜索_什么_。
SearchForm 組件當(dāng)然不知道它正在搜索什么,所以我們必須把責(zé)任傳遞給鏈。我們將會(huì)使用這種回調(diào)策略。
為了將搜索功能傳遞給鏈,我們的“SearchForm”將需要接受在提交表單時(shí)調(diào)用的函數(shù)。我們來(lái)定義一個(gè)我們稱之為 SearchForm 的屬性,我們可以傳遞給我們的SearchForm 組件。作為好的開(kāi)發(fā)人員,我們還會(huì)為這個(gè)onSubmit函數(shù)添加默認(rèn)的prop值和propType。因?yàn)槲覀兿胍_定onSubmit() 是被定義的,所以我們將把onSubmit的prop設(shè)置成一個(gè)必需的參數(shù):
class SearchForm extends React.Component { static propTypes = { onSubmit: React.PropTypes.func.isRequired, searchVisible: React.PropTypes.bool } // ... static defaultProps = { onSubmit: () => {}, searchVisible: false } // ... }
當(dāng)表單提交時(shí),我們可以直接從props調(diào)用這個(gè)函數(shù)。 由于我們?cè)诟櫸覀儬顟B(tài)下的搜索文本,所以我們可以在該狀態(tài)下使用searchText值調(diào)用該函數(shù),因此onSubmit() 函數(shù)只能獲取值并且不需要處理事件。
class SearchForm extends React.Component { // ... submitForm(event) { // prevent the form from reloading the entire page event.preventDefault(); // call the callback with the search value this.props.onSubmit(this.state.searchText); } }
現(xiàn)在,當(dāng)用戶按下enter時(shí),我們可以通過(guò)我們的Header 組件來(lái)調(diào)用props 中傳遞的onSubmit() 函數(shù)。
我們可以在我們的 Header 組件中使用這個(gè) SearchForm 組件,并傳遞我們定義的兩個(gè)屬性(searchVisible 和onSubmit):
import React from "react"; import SearchForm from "./SearchFormWithSubmit" class Header extends React.Component { constructor(props) { super(props); this.state = { searchVisible: false } } // toggle visibility when run on the state showSearch() { this.setState({ searchVisible: !this.state.searchVisible }) } render() { // Classes to add to the element let searchInputClasses = ["searchInput"]; // Update the class array if the state is visible if (this.state.searchVisible) { searchInputClasses.push("active"); } return () } } export default Header{this.props.title}{/* Adding an onClick handler to call the showSearch button */}
現(xiàn)在我們有一個(gè)搜索表單組件,可以在我們的應(yīng)用中使用和重用。 當(dāng)然,我們還沒(méi)有搜索任何東西。 我們來(lái)解決這個(gè)問(wèn)題,實(shí)現(xiàn)搜索。
[](#implementing-search)實(shí)現(xiàn)搜索要在我們的組件中實(shí)現(xiàn)搜索,我們希望將搜索責(zé)任從我們的 Header 組件傳遞到容器組件,我們稱之為 Panel。
首先,讓我們實(shí)現(xiàn)一個(gè)從 Panel 容器到Header 組件的子組件中將回調(diào)傳遞給父組件的模式。
在Header 組件上,我們來(lái)更新一個(gè)屬性的propTypes ,我們將它定義為onSearch屬性:
class Header extends React.Component { // ... } Header.propTypes = { onSearch: React.PropTypes.func }
在Header 組件的"submitForm()"函數(shù)里面,調(diào)用這個(gè)onSearch() 屬性,我們將傳入它:
class Header extends React.Component { // ... submitForm(val) { this.props.onSearch(val); } // ... } Header.propTypes = { onSearch: React.PropTypes.func }
請(qǐng)注意,我們的虛擬樹(shù)如下所示:
當(dāng)
更新時(shí),它會(huì)傳遞它的意識(shí),搜索輸入的變化到它的父組件 ,當(dāng)它將向上傳遞到 組件。 這種方法在React應(yīng)用中是_very common_,并為我們的組件提供了一套很好的功能隔離。
回到我們?cè)诘?天構(gòu)建的Panel 組件中,我們將把一個(gè)函數(shù)作為Header 的onSearch() 屬性傳遞給Header。 我們?cè)谶@里說(shuō)的是,當(dāng)提交搜索表單時(shí),我們希望搜索表單回調(diào)到頭部組件,然后調(diào)用 Panel 組件來(lái)處理搜索。
由于Header 組件不能控制內(nèi)容列表,所以Panel組件可以像我們?cè)谶@里定義一樣,我們_必須_將職責(zé)更多地傳遞給他們。
無(wú)論如何,我們的Panel 組件本質(zhì)上是我們之前使用的Content組件的副本:
class Panel extends React.Component { constructor(props) { super(props); this.state = { loading: false, // <~ set loading to false activities: data, filtered: data, } } componentDidMount() {this.updateData();} componentWillReceiveProps(nextProps) { // Check to see if the requestRefresh prop has changed if (nextProps.requestRefresh !== this.props.requestRefresh) { this.setState({loading: true}, this.updateData); } } handleSearch = txt => { if (txt === "") { this.setState({ filtered: this.state.activities }) } else { const { activities } = this.state const filtered = activities.filter(a => a.actor && a.actor.login.match(txt)) this.setState({ filtered }) } } // Call out to github and refresh directory updateData() { this.setState({ loading: false, activities: data }, this.props.onComponentRefresh); } render() { const {loading, filtered} = this.state; return () } } {/* Show loading message if loading */} {loading &&Loading} {/* Timeline item */} {filtered.map((activity) => ())}
我們更新我們的狀態(tài)以包括一個(gè)searchFilter字符串,這將只是搜索值:
class Panel extends React.Component { constructor(props) { super(props); this.state = { loading: false, searchFilter: "", activities: [] } } }
為了實(shí)際處理搜索,我們需要將onSearch() 函數(shù)傳遞給我們的Header 組件。 我們?cè)谖覀兊?b>Panel組件中定義一個(gè)onSearch() 函數(shù),并將其傳遞給render() 函數(shù)中的Header 屬性。
class Panel extends React.Component { // ... // after the content has refreshed, we want to // reset the loading variable onComponentRefresh() {this.setState({loading: false});} handleSearch(val) { // handle search here } render() { const {loading} = this.state; return () } }
我們?cè)谶@里所做的就是添加一個(gè)handleSearch() 函數(shù)并將其傳遞給標(biāo)題。 現(xiàn)在當(dāng)用戶鍵入搜索框時(shí),我們的Panel組件上的handleSearch() 函數(shù)將被調(diào)用。
為了_實(shí)現(xiàn)_搜索,我們需要跟蹤這個(gè)字符串,并更新我們的updateData() "函數(shù)來(lái)考慮搜索過(guò)濾。 首先讓我們把searchFilter 設(shè)置為狀態(tài)。 我們也可以強(qiáng)制內(nèi)容通過(guò)將加載設(shè)置為true來(lái)重新加載數(shù)據(jù),因此我們可以在一個(gè)步驟中執(zhí)行此操作:
class Panel extends React.Component { // ... handleSearch(val) { this.setState({ searchFilter: val, loading: true }); } // ... }
最后,我們更新我們的updateData()函數(shù)來(lái)考慮_搜索_帳戶。
class SearchableContent extends React.Component { // ... this.setState({loading: true}, this.updateData); // ... }
雖然這可能看起來(lái)很復(fù)雜,但它實(shí)際上幾乎與我們現(xiàn)有的updateData() 函數(shù)完全相同,除了我們更新了我們的fetch()結(jié)果以在json集合上調(diào)用filter() 方法。
所有的collection.filter() 函數(shù)都是運(yùn)行著每個(gè)元素傳遞的函數(shù),并且過(guò)濾_掉_返回偽造值的值,保留返回真值的值。我們的搜索功能只是在Github活動(dòng)的 actor.login (Github用戶)上查找匹配,以查看它是否正確匹配searchFilter 值。
隨著updateData() 功能的更新,我們的搜索完整了。
嘗試搜索auser。
現(xiàn)在我們有一個(gè)3層應(yīng)用組件來(lái)處理嵌套子組件的搜索。我們通過(guò)這個(gè)post從初級(jí)階段跳到了中級(jí)階段。靠著自己。這是一些重大的材料。確保你明白這一點(diǎn),因?yàn)槲覀儠?huì)經(jīng)常使用我們今天介紹的這些概念。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/84668.html
摘要:今天我們將討論創(chuàng)建組件的最終方案,即無(wú)狀態(tài)函數(shù)的純組件。今天我們正在研究一種處理提出的復(fù)雜數(shù)據(jù)的方法,稱為體系結(jié)構(gòu)。第天部署介紹今天,我們將探討部署我們的應(yīng)用所涉及的不同部分,以便外界可以使用我們的應(yīng)用。 本文轉(zhuǎn)載自:眾成翻譯譯者:iOSDevLog鏈接:http://www.zcfy.cc/article/3758原文:https://www.fullstackreact.com/3...
摘要:我們的應(yīng)用由一個(gè)單一的元素組成。讓我們通過(guò)構(gòu)建我們的第一個(gè)組件來(lái)開(kāi)始接觸這個(gè)力量。我們將把組件寫(xiě)成類。讓我們來(lái)看一個(gè)我們要調(diào)用的組件。然而,什么都不會(huì)在屏幕上呈現(xiàn)。 本文轉(zhuǎn)載自:眾成翻譯譯者:iOSDevLog鏈接:http://www.zcfy.cc/article/3799原文:https://www.fullstackreact.com/30-days-of-react/day-...
摘要:本文轉(zhuǎn)載自眾成翻譯譯者鏈接原文太棒了,我們已經(jīng)構(gòu)建了第一個(gè)組件。天前一章節(jié),我們開(kāi)始構(gòu)建我們的第一個(gè)組件。內(nèi)容部分內(nèi)有個(gè)不同的項(xiàng)目組件。決定劃分組件的深度比科學(xué)更顯得藝術(shù)。子組件當(dāng)組件嵌套在另一個(gè)組件中時(shí),它被稱為子組件。 本文轉(zhuǎn)載自:眾成翻譯譯者:iOSDevLog鏈接:http://www.zcfy.cc/article/3817原文:https://www.fullstackre...
摘要:本文轉(zhuǎn)載自眾成翻譯譯者鏈接原文今天,我們從一開(kāi)始就開(kāi)始。讓我們看看是什么,是什么讓運(yùn)轉(zhuǎn)起來(lái)。什么是是一個(gè)用于構(gòu)建用戶界面的庫(kù)。它是應(yīng)用程序的視圖層。所有應(yīng)用程序的核心是組件。組件是可組合的。虛擬完全存在于內(nèi)存中,并且是網(wǎng)絡(luò)瀏覽器的的表示。 本文轉(zhuǎn)載自:眾成翻譯譯者:iOSDevLog鏈接:http://www.zcfy.cc/article/3765原文:https://www.ful...
摘要:我們將為組件賦值,并使用選擇器來(lái)定位頁(yè)面上的元素,讓瀏覽器處理樣式。的工作方式是將因此命名父樣式作為子樣式的樣式。這通常是錯(cuò)誤的原因,因?yàn)轭愅ǔ>哂型ㄓ妹Q,并且易于覆蓋非特定類的類樣式。反之,我們的樣式名稱需要使用駝峰命名方式。 本文轉(zhuǎn)載自:眾成翻譯譯者:iOSDevLog鏈接:http://www.zcfy.cc/article/3820原文:https://www.fullsta...
閱讀 793·2021-11-25 09:43
閱讀 3063·2021-11-24 10:20
閱讀 1170·2021-10-27 14:18
閱讀 1163·2021-09-08 09:36
閱讀 3494·2021-07-29 14:49
閱讀 1880·2019-08-30 14:07
閱讀 3026·2019-08-29 16:52
閱讀 3143·2019-08-29 13:12