摘要:我們可以使用函數(shù)構(gòu)造函數(shù)將我們的組件轉(zhuǎn)換為狀態(tài)什么是函數(shù)構(gòu)造函數(shù)在中,函數(shù)是一個在創(chuàng)建對象時運行的函數(shù)。我們將使用構(gòu)造函數(shù)方法在對象創(chuàng)建時正確運行對象時設(shè)置實例變量。每當(dāng)一個有一個屬性被設(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)用,使其具有吸引力和交互性。
通過這一點,我們構(gòu)建了少數(shù)幾個組件,而沒有添加用戶交互。 今天我們將要改變它。
用戶交互瀏覽器是事件驅(qū)動的應(yīng)用程序。 用戶在瀏覽器中進(jìn)行的一切都會觸發(fā)一個事件,從點擊按鈕,甚至只是移動鼠標(biāo)。 在簡單的JavaScript中,我們可以監(jiān)聽這些事件并附加一個JavaScript函數(shù)與它們進(jìn)行交互。
例如,我們可以使用JS附加一個函數(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)行交互,因為React為我們使用props處理事件提供了一種方法。
例如,要從React上面的(相當(dāng)不起眼的)演示中收聽mousemove 事件,我們將設(shè)置onMouseMove (請注意事件名稱是駝峰命名的)。
console.log(evt)}> Move the mouse
React提供了很多props ,我們可以設(shè)置監(jiān)聽不同的瀏覽器事件,例如點擊,觸摸,拖動,滾動,選擇事件等等(參見事件文檔列出所有這些)。
要看看其中的一些在行動中,以下是一些小的演示,一些props ,我們可以傳遞我們的元素。 列表中的每個文本元素設(shè)置其列出的屬性。 嘗試使用列表查看事件在元素中的調(diào)用和處理方式。
我們將在我們的應(yīng)用中使用 onClick 屬性相當(dāng)多,所以熟悉它是一個好主意。 在我們的活動列表標(biāo)題中,我們有一個搜索圖標(biāo),我們還沒有與顯示一個搜索框關(guān)聯(lián)起來。
我們_想要_的交互是在用戶點擊搜索圖標(biāo)時顯示搜索。 回想一下,我們的Header組件是這樣實現(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)用戶點擊 元素時,我們需要運行一個函數(shù)來更新組件的狀態(tài),以便searchInputClasses對象更新。 使用onClick處理程序,這很簡單。
我們讓這個組件有狀態(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ù)是一個在創(chuàng)建對象時運行的函數(shù)。它返回對創(chuàng)建實例的prototype的Object函數(shù)的引用。
在純英文中,構(gòu)造函數(shù)是JavaScript運行時創(chuàng)建新對象時運行的函數(shù)。我們將使用構(gòu)造函數(shù)方法在對象創(chuàng)建時正確運行對象時設(shè)置實例變量。
當(dāng)使用ES6類語法創(chuàng)建對象時,我們必須在任何其他方法之前調(diào)用super() 方法。調(diào)用super() 函數(shù)調(diào)用父類的 constructor() 函數(shù)。我們將使用_相同參數(shù)_調(diào)用它,因為我們類的 constructor() 函數(shù)被調(diào)用。
當(dāng)用戶點擊按鈕時,我們將要更新狀態(tài)來表示searchVisible 標(biāo)志被更新。由于我們希望用戶能夠第二次點擊搜索圖標(biāo)后關(guān)閉/隱藏 字段,所以我們將_切換_該狀態(tài),而不是將其設(shè)置為true。
我們創(chuàng)建這個方法來綁定我們的點擊事件:
class Header extends React.Component { // ... showSearch() { this.setState({ searchVisible: !this.state.searchVisible }) } // ... }
最后,我們可以在icon元素上附加一個點擊處理程序(使用onClick 屬性)來調(diào)用我們新的 showSearch() 方法。 我們的 Header組件的整個更新的源代碼如下所示:
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 */}) } }
嘗試點擊搜索圖標(biāo)并觀看輸入字段出現(xiàn)并消失(動畫效果由CSS動畫處理)。
輸入事件無論何時在React中構(gòu)建表單,我們將使用React提供的輸入事件。最值得注意的是,我們最常使用 onSubmit() 和onChange()屬性。
我們更新我們的搜索框演示,以便在更新時捕獲搜索字段內(nèi)的文本。每當(dāng)一個 有一個 onChange()屬性被設(shè)置時,它會在該字段_改變_的每個時間調(diào)用函數(shù)。當(dāng)我們點擊它并開始輸入時,該函數(shù)將被調(diào)用。
使用這個屬性,我們可以捕捉到我們這個字段的價值。
讓我們創(chuàng)建一個新的子組件來包含一個 元素而不是更新我們的
我們創(chuàng)建一個我們稱之為SearchForm的新組件。這個新組件是一個有狀態(tài)的組件,因為我們需要保持搜索輸入的值(跟蹤它的變化):
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 (); } }
請注意,我們在我們的 字段上丟失了樣式。 由于我們不再在我們的新 組件中具有searchVisible狀態(tài),所以我們不能再使用它來對其進(jìn)行風(fēng)格化了。 _無論如何_,我們可以從我們的Header組件傳遞一個支持,該組件告訴SearchForm將輸入渲染為可見。
我們定義searchVisible 屬性(當(dāng)然使用React.PropTypes),并更新render函數(shù)以使用新的prop值來顯示(或隱藏)搜索。 我們還將為字段的可見性設(shè)置一個默認(rèn)值為false(因為我們的Header顯示/隱藏它很好):
class SearchForm extends React.Component { static propTypes = { onSubmit: React.PropTypes.func.isRequired, searchVisible: React.PropTypes.bool } // ... }
現(xiàn)在我們在 元素上有我們的樣式,讓我們添加用戶在搜索框中鍵入的功能,我們將要捕獲搜索字段的值。 我們可以通過將onChange參數(shù)附加到 元素上來實現(xiàn)這個工作流,并在每次更改 元素時傳遞一個函數(shù)來調(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)我們鍵入字段時,將會調(diào)用updateSearchInput() 函數(shù)。 我們將通過更新狀態(tài)來跟蹤表單的值。 在updateSearchInput() 函數(shù)中,我們可以直接調(diào)用this.setState() 來更新組件的狀態(tài)。
該值在event對象的目標(biāo)上保存為`event.target.value"。
class SearchForm extends React.Component { // ... updateSearchInput(e) { const val = e.target.value; this.setState({ searchText: val }); } // ... }
控制與不受控制我們正在創(chuàng)建所謂的不受控制的組件,因為我們沒有設(shè)置 元素的值。 我們現(xiàn)在不能對輸入的文本值提供任何驗證或后處理。
如果我們要驗證字段或操作 組件的值,我們將必須創(chuàng)建一個所謂的控件組件,這真的只是意味著我們使用value"傳遞一個值 屬性。 受控組件版本的render()` 函數(shù)將如下所示:
class SearchForm extends React.Component { render() { return ( ); } }
到目前為止,我們無法真正提交表單,所以我們的用戶無法真正搜索。 我們來改變一下 我們需要將component包含在一個DOM元素中,這樣我們的用戶可以按回車鍵提交表單。 我們可以使用 元素上的onSubmit支持來捕獲表單提交。
我們來更新render()函數(shù)來反映這個變化。
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()。這將阻止瀏覽器冒泡,從而使整個頁面的默認(rèn)行為重新加載(瀏覽器提交表單時的默認(rèn)功能)。
現(xiàn)在當(dāng)我們鍵入 字段并按回車鍵,submitForm() 函數(shù)被調(diào)用的事件對象。
那么好的,我們可以提交表單和內(nèi)容,但是什么時候我們實際上進(jìn)行搜索?為了演示目的,我們將把搜索文本傳遞給父子組件鏈,以便 Header 可以決定搜索_什么_。
SearchForm 組件當(dāng)然不知道它正在搜索什么,所以我們必須把責(zé)任傳遞給鏈。我們將會使用這種回調(diào)策略。
為了將搜索功能傳遞給鏈,我們的“SearchForm”將需要接受在提交表單時調(diào)用的函數(shù)。我們來定義一個我們稱之為 SearchForm 的屬性,我們可以傳遞給我們的SearchForm 組件。作為好的開發(fā)人員,我們還會為這個onSubmit函數(shù)添加默認(rèn)的prop值和propType。因為我們想要確定onSubmit() 是被定義的,所以我們將把onSubmit的prop設(shè)置成一個必需的參數(shù):
class SearchForm extends React.Component { static propTypes = { onSubmit: React.PropTypes.func.isRequired, searchVisible: React.PropTypes.bool } // ... static defaultProps = { onSubmit: () => {}, searchVisible: false } // ... }
當(dāng)表單提交時,我們可以直接從props調(diào)用這個函數(shù)。 由于我們在跟蹤我們狀態(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時,我們可以通過我們的Header 組件來調(diào)用props 中傳遞的onSubmit() 函數(shù)。
我們可以在我們的 Header 組件中使用這個 SearchForm 組件,并傳遞我們定義的兩個屬性(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)在我們有一個搜索表單組件,可以在我們的應(yīng)用中使用和重用。 當(dāng)然,我們還沒有搜索任何東西。 我們來解決這個問題,實現(xiàn)搜索。
[](#implementing-search)實現(xiàn)搜索要在我們的組件中實現(xiàn)搜索,我們希望將搜索責(zé)任從我們的 Header 組件傳遞到容器組件,我們稱之為 Panel。
首先,讓我們實現(xiàn)一個從 Panel 容器到Header 組件的子組件中將回調(diào)傳遞給父組件的模式。
在Header 組件上,我們來更新一個屬性的propTypes ,我們將它定義為onSearch屬性:
class Header extends React.Component { // ... } Header.propTypes = { onSearch: React.PropTypes.func }
在Header 組件的"submitForm()"函數(shù)里面,調(diào)用這個onSearch() 屬性,我們將傳入它:
class Header extends React.Component { // ... submitForm(val) { this.props.onSearch(val); } // ... } Header.propTypes = { onSearch: React.PropTypes.func }
請注意,我們的虛擬樹如下所示:
當(dāng)
更新時,它會傳遞它的意識,搜索輸入的變化到它的父組件 ,當(dāng)它將向上傳遞到 組件。 這種方法在React應(yīng)用中是_very common_,并為我們的組件提供了一套很好的功能隔離。
回到我們在第7天構(gòu)建的Panel 組件中,我們將把一個函數(shù)作為Header 的onSearch() 屬性傳遞給Header。 我們在這里說的是,當(dāng)提交搜索表單時,我們希望搜索表單回調(diào)到頭部組件,然后調(diào)用 Panel 組件來處理搜索。
由于Header 組件不能控制內(nèi)容列表,所以Panel組件可以像我們在這里定義一樣,我們_必須_將職責(zé)更多地傳遞給他們。
無論如何,我們的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)以包括一個searchFilter字符串,這將只是搜索值:
class Panel extends React.Component { constructor(props) { super(props); this.state = { loading: false, searchFilter: "", activities: [] } } }
為了實際處理搜索,我們需要將onSearch() 函數(shù)傳遞給我們的Header 組件。 我們在我們的Panel組件中定義一個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 () } }
我們在這里所做的就是添加一個handleSearch() 函數(shù)并將其傳遞給標(biāo)題。 現(xiàn)在當(dāng)用戶鍵入搜索框時,我們的Panel組件上的handleSearch() 函數(shù)將被調(diào)用。
為了_實現(xiàn)_搜索,我們需要跟蹤這個字符串,并更新我們的updateData() "函數(shù)來考慮搜索過濾。 首先讓我們把searchFilter 設(shè)置為狀態(tài)。 我們也可以強制內(nèi)容通過將加載設(shè)置為true來重新加載數(shù)據(jù),因此我們可以在一個步驟中執(zhí)行此操作:
class Panel extends React.Component { // ... handleSearch(val) { this.setState({ searchFilter: val, loading: true }); } // ... }
最后,我們更新我們的updateData()函數(shù)來考慮_搜索_帳戶。
class SearchableContent extends React.Component { // ... this.setState({loading: true}, this.updateData); // ... }
雖然這可能看起來很復(fù)雜,但它實際上幾乎與我們現(xiàn)有的updateData() 函數(shù)完全相同,除了我們更新了我們的fetch()結(jié)果以在json集合上調(diào)用filter() 方法。
所有的collection.filter() 函數(shù)都是運行著每個元素傳遞的函數(shù),并且過濾_掉_返回偽造值的值,保留返回真值的值。我們的搜索功能只是在Github活動的 actor.login (Github用戶)上查找匹配,以查看它是否正確匹配searchFilter 值。
隨著updateData() 功能的更新,我們的搜索完整了。
嘗試搜索auser。
現(xiàn)在我們有一個3層應(yīng)用組件來處理嵌套子組件的搜索。我們通過這個post從初級階段跳到了中級階段??恐约骸_@是一些重大的材料。確保你明白這一點,因為我們會經(jīng)常使用我們今天介紹的這些概念。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/84668.html
摘要:今天我們將討論創(chuàng)建組件的最終方案,即無狀態(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òu)建我們的第一個組件來開始接觸這個力量。我們將把組件寫成類。讓我們來看一個我們要調(diào)用的組件。然而,什么都不會在屏幕上呈現(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)建了第一個組件。天前一章節(jié),我們開始構(gòu)建我們的第一個組件。內(nèi)容部分內(nèi)有個不同的項目組件。決定劃分組件的深度比科學(xué)更顯得藝術(shù)。子組件當(dāng)組件嵌套在另一個組件中時,它被稱為子組件。 本文轉(zhuǎn)載自:眾成翻譯譯者:iOSDevLog鏈接:http://www.zcfy.cc/article/3817原文:https://www.fullstackre...
摘要:本文轉(zhuǎn)載自眾成翻譯譯者鏈接原文今天,我們從一開始就開始。讓我們看看是什么,是什么讓運轉(zhuǎn)起來。什么是是一個用于構(gòu)建用戶界面的庫。它是應(yīng)用程序的視圖層。所有應(yīng)用程序的核心是組件。組件是可組合的。虛擬完全存在于內(nèi)存中,并且是網(wǎng)絡(luò)瀏覽器的的表示。 本文轉(zhuǎn)載自:眾成翻譯譯者:iOSDevLog鏈接:http://www.zcfy.cc/article/3765原文:https://www.ful...
摘要:我們將為組件賦值,并使用選擇器來定位頁面上的元素,讓瀏覽器處理樣式。的工作方式是將因此命名父樣式作為子樣式的樣式。這通常是錯誤的原因,因為類通常具有通用名稱,并且易于覆蓋非特定類的類樣式。反之,我們的樣式名稱需要使用駝峰命名方式。 本文轉(zhuǎn)載自:眾成翻譯譯者:iOSDevLog鏈接:http://www.zcfy.cc/article/3820原文:https://www.fullsta...
閱讀 693·2021-11-25 09:43
閱讀 2964·2021-11-24 10:20
閱讀 1016·2021-10-27 14:18
閱讀 1088·2021-09-08 09:36
閱讀 3398·2021-07-29 14:49
閱讀 1796·2019-08-30 14:07
閱讀 2946·2019-08-29 16:52
閱讀 3057·2019-08-29 13:12