React基礎總結

React總結

入門

特色

  • Declarative(聲明式編碼)
  • Component-Based(組件化編碼)
  • Learn Once, Write Anywhere(支持客戶端與服務器渲染)
  • 高效

高效緣由

  • 虛擬(virtual)DOM, 不老是直接操做DOM
  • DOM Diff算法, 最小化頁面重繪, 減小重排重繪的次數

使用

相關js庫

  • react.js: React的核心庫
  • react-dom.js: 提供操做DOM的react擴展庫
  • babel.min.js: 解析JSX語法代碼轉爲純JS語法代碼的庫

編碼

//引入相關庫
<script type="text/javascript" src="../js/react.development.js"></script>
<script type="text/javascript" src="../js/react-dom.development.js"></script>
<script type="text/javascript" src="../js/babel.min.js"></script>

<script type="text/babel"> //必須聲明babel
  // 建立虛擬DOM元素
  const vDom = <h1>Hello React</h1> // 千萬不要加引號
  // 渲染虛擬DOM到頁面真實DOM容器中
  ReactDOM.render(vDom, document.getElementById('test'))
</script>

虛擬Dom

  • React提供了一些API來建立一種 特別 的通常js對象
var element = React.createElement('h1', {id:'myTitle'},'hello')
  • 上面建立的就是一個簡單的虛擬DOM對象
  • 虛擬DOM對象最終都會被React轉換爲真實的DOM
  • 咱們編碼時基本只須要操做react的虛擬DOM相關數據, react會轉換爲真實DOM變化而更新界面
  • 建立虛擬Dom方法
<body>
            <div id="test"></div>
        </body>
        
<script type="text/babel">
 // 建立虛擬DOM對象
 const vDom1 = React.createElement('p',{id: 'myId1', className: 'myClass1'}, '珂朵莉',vDom3);
// 將虛擬DOM對象插入到頁面的指定容器中,渲染虛擬DOM(元素)
ReactDOM.render(vDom1, document.getElementById('test1')); //方法一

 //方法二
    const id = 'myId2';
    const content = '我永遠喜歡珂朵莉';
    const vDom3 = React.createElement('span', {}, 'daisiki');
    const vDom2 = <div><h2 id={id } className="myClass2">{content}</h2>{vDom3}</div>
    // 將虛擬DOM對象插入到頁面的指定容器中
    ReactDOM.render(vDom2, document.getElementById('test2'));
    const list = ['1', '2', '3', '4'];
    ReactDOM.render(
        <ul>
            { list.map(( item,index) => <li key={index}>{item}</li> ) }
        </ul>
        ,document.getElementById('test3')) 
<script>

JSX

1)全稱:  JavaScript XML
2)react定義的一種相似於XML的JS擴展語法: XML+JS
3)做用: 用來建立react虛擬DOM(元素)對象
    a.var ele = <h1>Hello JSX!</h1>
    b.注意1: 它不是字符串, 也不是HTML/XML標籤
    c.注意2: 它最終產生的就是一個JS對象
4)標籤名任意: HTML標籤或其它標籤
5)標籤屬性任意: HTML標籤屬性或其它
6)基本語法規則
    a.遇到 <開頭的代碼, 以標籤的語法解析: html同名標籤轉換爲html同名元素, 其它標籤須要特別解析
    b.遇到以 { 開頭的代碼,以JS語法解析: 標籤中的js代碼必須用{ }包含,  //待定:* if/for循環 不能用
7)babel.js的做用
    a.瀏覽器不能直接解析JSX代碼, 須要babel轉譯爲純JS的代碼才能運行
    b.只要用了JSX,都要加上type="text/babel", 聲明須要babel來處理

React面向組件編程

自定義組件(Component) :

定義組件(2種方式)javascript

/*方式1: 工廠函數組件(簡單組件)*/
function MyComponent () {
  return <h2>工廠函數組件(簡單組件)</h2>
}

/*方式2:  ES6類組件(複雜組件)*/
class MyComponent2 extends React.Component {
  render () {
    console.log(this) // MyComponent2的實例對象
    return <h2>ES6類組件(複雜組件)</h2>
  }
}

渲染組件標籤html

ReactDOM.render(<MyComponent />, document.getElementById('example1'))

注意

  • 組件名必須首字母大寫
  • 虛擬DOM元素只能有一個根元素
  • 虛擬DOM元素必須有結束標籤前端

    • 單標籤 <xx />: 當組件沒有內容時,直接用單標籤
    • 雙標籤 <xx></xx> : 當組件有內容時,能夠用雙標籤

render()渲染組件標籤的基本流程

  • React內部會建立組件實例對象
  • 獲得包含的虛擬DOM並解析爲真實DOM
  • 插入到指定的頁面元素內部

React 的 三大屬性

state

  • state是組件對象最重要的屬性, 值是對象(能夠包含多個數據)
  • 組件被稱爲"狀態機", 經過更新組件的state來更新對應的頁面顯示(從新渲染組件)

用法

  • 初始化java

    • 在constructor中定義 this.state = {xxx: xxx},
    • 不在constructor定義:state = {xxx: xxx}
  • 讀取 this.state.xxx
  • 更新 this.setState({xxx: xxx})

注意

  1. setState 只在合成事件和鉤子函數中是「異步」的,在原生事件和 setTimeout 中都是同步的。
  2. 若是須要獲取「異步」場景的 setState 的值 --> this.setState(partial, callback) 在callback中拿到最新的值
  3. 若是要在「異步」場景更新屢次 setState --> this.setState((prevState, props) => {return newState})

props

  • 每一個組件對象都會有props(properties的簡寫)屬性
  • 組件標籤的全部屬性都保存在props中

做用

  • 經過標籤屬性從組件外向組件內傳遞變化的數據
  • 注意: 組件內部不要修改props數據

使用

  • 約束屬性的類型和必要性 static propTypes = {xxx: PropTypes.func.isRequired}
  • 定義屬性的默認值 static defaultProps = {xxx: xxx}
  • 內部讀取某個屬性值,獲取組件外向組件內傳遞的標籤屬性 this.props.xxx / const { name, age, sex } = this.props;
  • 擴展屬性: 將對象的全部屬性經過props傳遞,設置 <List name={xxx}> / <Person {...person}/>
  • 默認屬性值: 原來方案Person.defaultProps = {name: 'Mary'} 最新方案:static defaultProps = {

name: 'Mary'}node

  • 組件類的構造函數
constructor (props) {
super(props)
console.log(props) // 查看全部屬性
}

區別一下組件的props和state屬性

  • state: 組件自身內部可變化的數據
  • props: 從組件外部向組件內部傳遞數據, 組件內部只讀不修改

refs

介紹

組件內的標籤均可以定義ref屬性來標識本身, 用來獲取DOM元素
在組件中能夠經過this.msgInput來獲得對應的真實DOM元素react

a.    <input type="text" ref={this.createRef}/> (推薦使用)
b.    <input type="text" ref={input => this.funcRef = input}/> 
c.    <input type="text" ref="stringRef" /> (即將廢棄)
d.    回調函數在組件初始化渲染完或卸載時自動調用

做用: 經過ref獲取組件內容特定標籤對象, 進行讀取其相關數據webpack

使用

1.<input type="text" ref={this.createRef}/>
 2.<input type="text" ref={(input) => this.funcRef = input}/>
 3.<input type="text" ref="stringRef"/>
     constructor(props) {
        super(props);
        this.createRef = React.createRef();
      }
      
// 獲取input標籤的值
1. this.createRef.current
2. console.log(this.funcRef);
3. console.log(this.refs.stringRef);

事件處理

  • 經過onXxx屬性指定組件的事件處理函數(注意大小寫)ios

    • a.React使用的是自定義(合成)事件, 而不是使用的原生DOM事件
    • b.React中的事件是經過事件委託方式處理的(委託給組件最外層的元素)
  • 經過event.target獲得發生事件的DOM元素對象git

    <input onFocus={this.handleClick}/>
    handleFocus(event) {
    event.target  //返回input對象
    }

強烈注意

  • 1)組件內置的方法中的this爲組件對象
  • 2)在組件類中自定義的方法中this爲undefined程序員

    • a. 強制綁定this: 經過函數對象的bind()
    • b. 箭頭函數(ES6模塊化編碼時才能使用)
  • React組件中函數this指向規則

    • 組件內置的方法中的this爲組件的實例對象
    • 在組件類中自定義的方法中this爲undefined
    • 經過函數對象的bind()強制綁定this指向爲組件實例對象,也就是this
    • 箭頭函數this就能指向實例對象(ES6模塊化編碼時才能使用)
    • 工廠函數組件中this爲undefined
    • ES6類組件(複雜組件)this爲組件的實例對象

表單的組件分類

  • 受控組件: 表單項輸入數據能自動收集成狀態(onChange)
  • 非受控組件: 須要時才手動讀取表單輸入框中的數據(onClick)

組件化編碼流程和套路

組件編碼流程:

1.拆分組件:根據頁面功能拆分
  APP
  AddTodo
  TodoList
2.實現靜態組件
  先實現大的組件(最外層的),再實現裏面的組件
  先有一個基本的顯示效果
3.實現動態組件
  1.需不須要定義狀態數據? 看頁面是否有變化,有變化就要定義狀態數據
  2.狀態數據定義在哪裏? APP
     若是數據是單個組件須要,就定義在單個組件中
     若是數據是多個組件須要,就定義在公共的父組件中,也就是引用了那幾個多組件的父組件
  3.狀態數據定義爲何?
     定義成對象、數組、基本數據類型。
     方便插入數據和遍歷展現,因此用數組
 4.子組件如何操做父組件的數據
     父組件定義操做數據的方法(數據再哪,操做數據的方法就在在哪)
     父組件將操做數據的方法傳給子組件,子組件調用就能修改父組件的數據

組件的生命週期函數

理解

  • 組件對象從建立到死亡它會經歷特定的生命週期階段
  • React組件對象包含一系列的勾子函數(生命週期回調函數), 在生命週期特定時刻回調
  • 咱們在定義組件時, 能夠重寫特定的生命週期回調函數, 作特定的工做

生命週期詳述

  • 組件的三個生命週期狀態:

    • Mount:插入真實 DOM,渲染時
    • Update:被從新渲染,更新時
    • Unmount:被移出真實 DO,,卸載時
  • React 爲每一個狀態都提供了勾子(hook)函數

    • componentWillMount()
    • componentDidMount()
    • componentWillUpdate()
    • componentDidUpdate()
    • componentWillUnmount()
  • 生命週期流程:

    • 第一次初始化渲染顯示: ReactDOM.render()

      • constructor(): 建立對象初始化state
      • componentWillMount() : 將要插入回調
      • render() : 用於插入虛擬DOM回調
      • componentDidMount() : 已經插入回調
    • 每次更新state: this.setSate()

      • componentWillUpdate() : 將要更新回調
      • render() : 更新(從新渲染)
      • componentDidUpdate() : 已經更新回調
    • 移除組件: ReactDOM.unmountComponentAtNode(containerDom)

      • componentWillUnmount() : 組件將要被移除回調

生命週期函數做用:

constructor()`
    * 初始化state
    * 修改函數的this指向
    * 只會執行一次
 static getDerivedStateFromProps(nextProps, prevState)`
    * 通常不用
    * 使組件可以根據props的更改來更新其內部狀態
 render()`
    * 渲染組件
 componentDidMount()`
    * 發送ajax請求
    * 執行異步任務
    * 只會執行一次
 shouldComponentUpdate(nextProps, nextState)`
    * react性能優化,減小沒必要要的render
 getSnapshotBeforeUpdate(prevProps, prevState)`
    * 通常不用
    * 能夠在渲染以前獲得DOM對象從而獲取一些信息
 componentDidUpdate(prevProps, prevState, snapshot)`
    * 更新組件完成時對DOM進行操做
    * 發送ajax請求(注意不要陷入死循環)
 componentWillUnmount()`
    * 清除定時器,收尾工做等

重要的生命週期(必須掌握)

  • constructor()
  • render() 初始化渲染或更新渲染調用
  • componentDidMount() 開啓監聽, 發送ajax請求
  • componentWillUnmount() 作一些收尾工做, 如: 清理定時器
  • componentDidUpdate() 能夠獲取更新後DOM元素,從而進行操做
  • shouldComponentUpdate 專門用來作React性能優化的:將以前的狀態/屬性和當前的狀態/屬性進行對比,若是同樣,就不更新,若是不同就更新
    返回值爲true就更新
    返回值爲false就不更新

React腳手架

介紹

  • xxx腳手架: 用來幫助程序員快速建立一個基於xxx庫的模板項目

    • a. 包含了全部須要的配置
    • b. 指定好了全部的依賴
    • c. 能夠直接安裝/編譯/運行一個簡單效果
  • react提供了一個用於建立react項目的腳手架庫: create-react-app
  • 項目的總體技術架構爲: react + webpack + es6 + eslint + babel
  • 使用腳手架開發的項目的特色: 模塊化, 組件化, 工程化

建立項目並啓動

npm install -g create-react-app  //全局安裝create-react-app
create-react-app hello-react    //建立一個項目名稱爲hello-react的腳手架              
npm start                      //必須在hello-react文件目錄下運行

react腳手架項目結構

ReactNews
    |--node_modules---第三方依賴模塊文件夾
    |--public
        |-- index.html-----------------主頁面
    |--src------------源碼文件夾
        |--components-----------------react組件
        |--index.js-------------------應用入口js
    |--.gitignore------git版本管制忽略的配置
    |--package.json----應用包配置文件 
    |--README.md-------應用描述說明的readme文件

react ajax

前置說明

  • React自己只關注於界面, 並不包含發送ajax請求的代碼
  • 前端應用須要經過ajax請求與後臺進行交互(json數據)
  • react應用中須要集成第三方ajax庫(或本身封裝)

經常使用的ajax請求庫

  • jQuery: 比較重, 若是須要另外引入不建議使用
  • axios: 輕量級, 建議使用

    • a. 封裝XmlHttpRequest對象的ajax
    • b. promise風格
    • c. 能夠用在瀏覽器端和node服務器端
  • fetch: 原生函數, 但老版本瀏覽器不支持

componentDidMount(){
            //發送Ajax請求
          /* axios.get('https://api.github.com/search/repositories?q=r&sort=stars')
                //axios.get('/user', {params: {q:r,sort:stars}})
                //axios.post('/user', {firstName: 'Fred',lastName: 'Flintstone'})
               .then(response => {
                   const {name, html_url} = response.data.items[0];
                   this.setState({ name,url: html_url})
                    })
               .catch(err =>{
                   console.log(err);
                   })*/
         fetch('https://api.github.com/search/repositories?q=v&sort=stars')
            //get: fetch(url) post: fetch(url, {method: "POST" body:JSON.stringify(data),})
               .then(res => res.json())
               .then(response =>{
                   console.log(response);
                   const {name, html_url} = response.items[0];
                   this.setState({name,url: html_url })
                    })
               .catch(err =>{
                   console.log(err);
               })
        }

react路由

相關理解

react-router的理解

  • react的一個插件庫
  • 專門用來實現一個SPA應用
  • 基於react的項目基本都會用到此庫

SPA的理解

  • 單頁Web應用(single page web application,SPA)
  • 整個應用只有一個完整的頁面
  • 點擊頁面中的連接不會刷新頁面, 自己也不會向服務器發請求
  • 當點擊路由連接時, 只會作頁面的局部更新,網址也會對應的改變
  • 數據都須要經過ajax請求獲取, 並在前端異步展示

路由的理解

什麼是路由?
  • 一個路由就是一個映射關係(key:value)
  • key爲路由路徑, value多是function/component
路由分類
  • 後臺路由: node服務器端路由, value是function, 用來處理客戶端提交的請求並返回一個響應數據

    • a. 註冊路由: router.get(path, function(req, res))
    • b. 當node接收到一個請求時, 根據請求路徑找到匹配的路由, 調用路由中的函數來處理請求, 返回響應數據
  • 前臺路由: 瀏覽器端路由, value是component(組件), 當請求的是路由path時, 瀏覽器端前沒有發送http請求, 但界面會更新顯示對應的組件

    • a.註冊路由: <Route path="/about" component={About} />
    • b.當瀏覽器的hash變爲#about時, 當前路由組件就會變爲About組件
區別:
* 前端路由
    * 不須要發送請求
    * 不會刷新整個頁面,局部更新
    * 會修改url地址和瀏覽器歷史記錄
    * value是component
* 後端路由
    * 會發送請求
    * 會刷新整個頁面
    * 會修改url地址和瀏覽器歷史記錄
    * value是callback
  • 使用前端路由的做用:

    • 用來開發SPA(單頁面應用)
    • 整個應用一個完整頁面
    • 不須要發送請求
    • 不會刷新整個頁面,局部更新
    • 會修改url地址和瀏覽器歷史記錄

前端路由的實現

history庫

a.    網址: https://github.com/ReactTraining/history
b.    管理瀏覽器會話歷史(history)的工具庫
c.    包裝的是原生BOM中window.history和window.location.hash

history API

a.    History.createBrowserHistory(): 獲得封裝window.history的管理對象
b.    History.createHashHistory(): 獲得封裝window.location.hash的管理對象
c.    history.push(): 添加一個新的歷史記錄
d.    history.replace(): 用一個新的歷史記錄替換當前的記錄
e.    history.goBack(): 回退到上一個歷史記錄
f.    history.goForword(): 前進到下一個歷史記錄
g.    history.listen(function(location){}): 監視歷史記錄的變化

react-router相關API

組件

1)    <BrowserRouter>
         browserHistory 是使用 React-Router 的應用推薦的 history方案。
         它使用瀏覽器中的 History API 用於處理 URL,建立一個像example.com/list/123這樣真實的 URL 
         <BrowserRouter><App /></BrowserRouter>
    2)    <HashRouter>
        
    3)    <Route>
         <Route path="/about" component={About}/>
         <Route path="/home/message/:id" component={MessageDetail}/>
          一旦url變爲path對應的值,就加載component中的組件進行顯示
    4)    <Redirect>
         <Redirect to="/about"/>
         什麼路徑都匹配,一旦匹配上就跳轉到指定網址,與Switch配合使用
    5)    <Link> 
          只修改url的地址,不會發送請求      
          <Link to="/home">珂朵莉</Link>
    6)    <NavLink> 
         只修改url的地址,不會發送請求,而且多了一個class:active  
        export default function MyNavLink(props) {
           return <NavLink {...props} activeClassName='activeClass'/>
           }
        <MyNavLink to="/about">About</MyNavLink>
    7)    <Switch>
        切換顯示(針對內部組件 - 子組件) --> 從上到下匹配,一旦有一個匹配上,其餘就不看了
        <Switch>
           <Route path="/about" component={About}/>
           <Route path="/home" component={Home}/>
           <Redirect to="/about"/>
        </Switch>
  • 路由組件:經過Route組件加載的組件(import { withRouter } from 'react-router-dom')

    • history 修改瀏覽器歷史記錄
    • location 獲取請求path
    • match 獲取params參數
    • withRouter 做用:給非路由組件傳遞路由組件三個屬性(history、location、match)@withRouter

react-ui庫

material-ui(國外)

ant-design(國內螞蟻金服)

相關文章
相關標籤/搜索