摘要:小明小明兒子,可以看到組件顯示了父組件的。小明受控組件和非受控組件受控組件和非受控組件這些都是指的表單組件,當一個表單的值是通過改變的而不是通過是受控組件,否則就是非受控組件。
react眾所周知的前端3大主流框架之一,由于出色的性能,完善的周邊設施風頭一時無兩。本文就帶大家一起掌握react。
jsx語法前端MVVM主流框架都有一套自己的模板處理方法,react則使用它獨特的jsx語法。在組件中插入html類似的語法,簡化創建view的流程。
下面讓我們來認識一下構建的兩種元素
原生元素ReactDOM.render((), document.getElementById("root"))標題
通過簡單的語法頁面就會被插入一個div+一個h1標簽。原生的html元素可以被直接使用。以上的語法并不是js支持的語法,需要被轉換之后才能運行。
自定義元素react強大之處就在于可以組件的自定義,實現組件的復用。如果我們創建了一個組件。我們也可以通過jsx語法調用。
import * as React from "react" class Page extends React.Component { render() { return (home111 © ? ua9) } } ReactDOM.render((), document.getElementById("root"))
我們定義了一個Page組件,可以在jsx里面像調用html一樣直接調用。
插入動態數據let name = "hi" ReactDOM.render(({name}), document.getElementById("root"))
使用{}就可以插入數據,但是{}中間的必須是js表達式,不能是語句。如果表達式的執行結果是一個數組,則會自動join。
注釋jsx語法和html語法一樣,也是可以插入注釋,只不過寫的時候有一些區別
子組件注釋let name = "hi" ReactDOM.render(({/* 注釋 */} {name}), document.getElementById("root"))
在子組件中插入注釋,需要使用{}包裹起來,在/ /之間插入注釋文字。
屬性注釋let name = "hi" ReactDOM.render(({name}), document.getElementById("root"))
在標簽中間,可以插入一個多行注釋,類似上面的代碼。
屬性props可以向使用html的attr一樣使用屬性,就像下面img的src一樣
let name = "hi" ReactDOM.render((), document.getElementById("root"))
如果需要傳遞動態屬性,使用{},多個屬性,使用展開運算符
let props = { src: "1.png", alt: "1圖片" } ReactDOM.render((), document.getElementById("root"))
兩個轉換,class-->className for-->htmlFor
因為class和for是javascript關鍵字,所以這里需要用轉換之后名稱
ReactDOM.render((), document.getElementById("root"))姓名:
布爾屬性
如果一個屬性的值是布爾值,當這個值是true的時候則可以省略=后面的值,只保留key。
ReactDOM.render((), document.getElementById("root"))
原生元素的自定義屬性
react對元素屬性做了校驗,如果在原生屬性上使用此元素不支持的屬性,則不能編譯成功。必須使用data-前綴
ReactDOM.render((插入html), document.getElementById("root"))
如果動態的插入html元素,react出于安全性考慮會自動幫我們轉義。所以一定要動態的插入元素的話,使用dangerouslySetInnerHTML
ReactDOM.render((React組件創建 React.createClass), document.getElementById("root"))test"}}>
這是舊版本的api,使用React.createClass創建組件,配套的一些api,有getDefaultProps, getinitialstate。官方已經不建議使用了,使用下面新的api替代。
ES6 classesimport * as React from "react" class Page extends React.Component { render() { return (home) } }
這是一個實現了render方法的class。也是一個基本的react組件。
無狀態函數function Button(props, context) { return ( ); }
純函數,不存在state,只接受props和state。純函數有優點,優點就是易于測試,無副作用。
React數據流 statestate是組件的內部狀態,需要在視圖里面用到的狀態,才需要放到state里面去。如下,我們在類上創建一個state屬性,在視圖里面通過使用this.state.name去引用。而這里的state定義則代替的是getinitialstate方法。
import * as React from "react" class Page extends React.Component { state = { name: "小明" } render() { return ({this}) } }
如何更新state呢,直接更改state其實可以可以的,不過這樣子無法觸發組件視圖的更新機制。所以使用setState()api。值得注意的是setState是異步的,原因是react內部需要對setState做優化,不是state變了立刻去更新視圖,而是攔截一部分state的改變,等到合適的時機再去更新視圖。
import * as React from "react" class Page extends React.Component { state = { name: "小明" } render() { setTimeout(() => this.setState({name: "小明兒子"}), 5000) return ({this.state.name}) } }
真實開發中絕不要在render函數里面去更改state,以上只是為了演示props
props是組件之間傳遞數據的最主要api, react推崇的是自頂向下的數據流向,也就是組件的數據要從父組件傳給子組件。如果子組件需要向父組件傳遞數據,則需要使用回調函數的方式。
import * as React from "react" class Child extends React.Component { render() { return ({this.props.parentName}) } } class Parent extends React.Component { state = { name: "小明" } render() { setTimeout(() => this.setState({name: "小明兒子"}), 5000) return () } }
可以看到Child組件顯示了父組件的name。當父組件狀態更新了,子組件同步更新。那如何在子組件中更改父組件狀態呢?答案是回調函數。
import * as React from "react" class Child extends React.Component { update() { this.props.onChange("小明名字改了") } render() { return ({this.props.parentName}) } } class Parent extends React.Component { state = { name: "小明" } changeName(name) { this.setState({ name }) } render() { setTimeout(() => this.setState({name: "小明兒子"}), 5000) return () } }
注意哈:props是不可以更改的,這既不符合react單向數據流思想,也為維護帶來災難。
事件react里面的用戶事件都是合成事件,被React封裝過。內部使用的還是事件的委托機制。
常用的事件有點擊事件onClick,input的onChange事件等,官網都可以查到。
就像上文一樣,我們綁定事件的方式很奇怪,使用了bind來顯示綁定this的指向。因為傳遞到組件內部的只是一個函數,而脫離了當前對象的函數的this指向是不能指到當前組件的,需要顯示指定。
通過bind 構造器內部指定import * as React from "react" class Child extends React.Component { constructor(props) { super(props) this.update = this.update.bind(this) } update() { this.props.onChange("小明名字改了") } render() { return (箭頭函數{this.props.parentName}) } }
import * as React from "react" class Child extends React.Component { update => e = { this.props.onChange("小明名字改了") } render() { return (裝飾器{this.props.parentName}) } }
import * as React from "react" class Child extends React.Component { constructor(props) { super(props) } @autoBind update() { this.props.onChange("小明名字改了") } render() { return ({this.props.parentName}) } }
裝飾器是es7語法,如果需要使用需要安裝對應的babel:present版本。而typescript則原生支持。
autoBind原理大概就是劫持get方法,get時改變this指向如何獲得evnt原生事件
通過e.nativeEvent獲取原生事件對象
import * as React from "react" class Child extends React.Component { constructor(props) { super(props) this.update = this.update.bind(this) } update(e) { console.log(e.nativeEvent) } render() { return (解決冒泡和取消默認事件) } }
e.preventDefault() //取消默認行為
e.stopPropagation() //取消冒泡
這個和瀏覽器原生事件處理方案是一致的。問題是我們只可以調合成事件的e的方法,不可以通過e.nativeEvent方法做這些操作,原因是上文講過的委托。
ReactDom ref特殊的props,ref組件對象的引用,現在官方也不建議直接給ref賦值,需要通過函數來賦值。
ReactDOM.render((render), document.getElementById("root"))this.c = ref} any-ss="text"/>
頂層api,只有在根組件時候才需要使用。第一個參數是Component,第二個參數是dom節點
findDOMNode通過傳入component實例獲取此component根dom節點,在這里可以去dom節點進行操作了,雖然極其不建議這么做,但是你確實可以做。
unmountComponentAtNode卸載此組件,并銷毀組件state和事件
接收組件的引用,也就是ref。僅僅是取消掛載,組件還在,如果需要徹底清除的話,需要手動刪掉此dom。
表單 onchange配合value與vue框架不同的是,react如果要實現表單元素變化,狀態同步更新,必須要自己去監聽表單事件。
import * as React from "react" class Child extends React.Component { state = { name: "小明" } constructor(props) { super(props) this.update = this.update.bind(this) } update(e) { this.setState({ name: e.target.value }) } render() { return (受控組件和非受控組件) } }
受控組件和非受控組件這些都是指的表單組件,當一個表單的值是通過value改變的而不是通過defaultValue是受控組件,否則就是非受控組件。
下面組件中的input就是受控組件
import * as React from "react" class Child extends React.Component { state = { name: "小明" } constructor(props) { super(props) this.update = this.update.bind(this) } update(e) { this.setState({ name: e.target.value }) } render() { return () } }
下面組件中的input是非受控組件
import * as React from "react" class Child extends React.Component { state = { name: "小明" } constructor(props) { super(props) this.update = this.update.bind(this) } update(e) { this.setState({ name: e.target.value }) } render() { return (組件之間通訊 父子之間通訊) } }
父子之間通訊又分為父->子,子->父。
因為react單向數據流向的緣故,父->子通信的話直接通過props。父組件數據變動,直接傳遞給子組件。
子->父組件之間就要通過回調函數來通信了,父組件傳遞一個回調函數給子組件,子組件通過調用此函數的方式通知父組件通信。
跨級組件通信react為了實現祖先組件和后輩組件之間的通信問題,引入了contextApi。
class Button extends React.Component { render() { return ( ); } } Button.contextTypes = { color: React.PropTypes.string }; class Message extends React.Component { render() { return ({this.props.text}); } } class MessageList extends React.Component { getChildContext() { return {color: "purple"}; } render() { const children = this.props.messages.map((message) =>); return {children}; } } MessageList.childContextTypes = { color: React.PropTypes.string };
MessageList中的color會自動更新到兒孫組件里面去,實現跨級啊通信。如果需要反過來通信,則需要借助其他工具,比如事件系統(Pub/Sub)。
沒有嵌套關系組件之間通信組件之間通信最主流的兩種方式脫胎于觀察這模式和中介者模式這兩種。
跨級之間通信現在最主流的方式就是觀察這模式的實現Pub/Sub,react社區中的redux也是使用這種方式實現的。
vue2.X版本也去掉了跨組件通信的功能。那如何在2.x中做跨組件通信呢?如果不借助外力的話,是不是可以使用$parent和$childen的遞歸調用實現全局組件通信呢?比如我想廣播一個事件,我就查找到所有的子組件,挨個觸發$emit(xx),上報一個事件也是同理,只不過需要查找所有的$parent。結合起來就可以實現組件之間的通信,只不過這種查找效率比較低,需要慎用和優化
創建了一個程序員交流微信群,大家進群交流IT技術
如果已過期,可以添加博主微信號15706211347,拉你進群
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/97409.html
摘要:前言上一次我們對的應用進行了一次全面的分析,這一次我們來聊聊。 showImg(https://segmentfault.com/img/remote/1460000020077803?w=1280&h=853); 前言 上一次我們對Paging的應用進行了一次全面的分析,這一次我們來聊聊WorkManager。 如果你對Paging還未了解,推薦閱讀這篇文章: Paging在Recy...
摘要:采用完全獨立于任何程序語言的文本格式,使成為理想的數據交換語言為什么需要提到,我們就應該和來進行對比。也是一種存儲和交換文本信息的手段。那么好在哪里呢比更小更快,更易解析。使用的時候,也支持將轉成但是,我們不一定使用框架來做開發呀。 什么是JSON JSON:JavaScript Object Notation 【JavaScript 對象表示法】 JSON 是存儲和交換文本信息的語法...
摘要:目錄前言架構安裝第一個爬蟲爬取有道翻譯創建項目創建創建解析運行爬蟲爬取單詞釋義下載單詞語音文件前言學習有一段時間了,當時想要獲取一下百度漢字的解析,又不想一個個漢字去搜,復制粘貼太費勁,考慮到爬蟲的便利性,這篇文章是介紹一個爬蟲框架, 目錄 前言 架構 安裝 第一個爬蟲:爬取有道翻譯 創建項目 創建Item 創建Spider 解析 運行爬蟲-爬取單詞釋義 下載單詞語音文件 ...
摘要:如果我們想要多次輸出類中的成員信息,就需要多次書寫方法每用一次就得寫而調用就簡單多了補充兩者等價輸出結果。注一般選擇重寫方法,比較對象的成員變量值是否相同,不過一般重寫都是自動生成。 第三階段 JAVA常見對象的學習 第一章 常見對象——Object類 引言: 在講解Object類之前,我們不得不簡單的提一下什么是API,先貼一組百度百科的解釋: API(Application Pro...
摘要:相信很多人在格式化字符串的時候都用的語法,提出一種更先進的格式化方法并成為的標準用來替換舊的格式化語法,從開始已經實現了這一方法其它解釋器未考證。 showImg(https://segmentfault.com/img/remote/1460000018650325); 相信很多人在格式化字符串的時候都用%s % v的語法,PEP 3101 提出一種更先進的格式化方法 str.for...
閱讀 2327·2021-09-22 15:27
閱讀 3180·2021-09-03 10:32
閱讀 3510·2021-09-01 11:38
閱讀 2505·2019-08-30 15:56
閱讀 2221·2019-08-30 13:01
閱讀 1546·2019-08-29 12:13
閱讀 1429·2019-08-26 13:33
閱讀 900·2019-08-26 13:30